Blockchain

塊 9 事務 1 輸出 0 ScriptPubKey openssl 驗證失敗

  • November 22, 2021

我正在嘗試使用 openssl 檢查位於事務 #1 bloc #9 的輸出 #0 的 ScriptPubKey 中的公鑰。我正在使用 Python 創建一個 DER 文件,並使用 openssl 對其進行檢查。

ScriptPubKey 值為:

0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3

我創建 DER 文件的 Python 程式碼是:

scriptPubKey = block9.transactions[0].outputs[0].scriptPubKey[1:-1]
x = scriptPubKey[1:1+32]
y = scriptPubKey[1+32:]
publicKey = bytearray ([0x03, len (scriptPubKey) + 1, 0x00]) + scriptPubKey
algorithmIdentifierId = b'\x06\x07\x2a\x86\x48\xce\x3d\x02\x01'
algorithmIdentifierParameters = b'\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07'
algorithmIdentifier = algorithmIdentifierId + algorithmIdentifierParameters
publicKey = bytearray ([0x30, len (algorithmIdentifier)]) + algorithmIdentifier + publicKey
publicKey = bytearray ([0x30, len (publicKey)]) + publicKey
file = open (f'public.der', 'wb')
file.write (publicKey)
file.close ()

執行此程式碼後,我得到一個public.der我使用 openssl 檢查的。第一的; 我檢查了 ASN.1 語法,這是正確的:

$ openssl asn1parse -inform der -in public.der 
   0:d=0  hl=2 l=  89 cons: SEQUENCE          
   2:d=1  hl=2 l=  19 cons: SEQUENCE          
   4:d=2  hl=2 l=   7 prim: OBJECT            :id-ecPublicKey
  13:d=2  hl=2 l=   8 prim: OBJECT            :prime256v1
  23:d=1  hl=2 l=  66 prim: BIT STRING

然後我檢查密鑰本身,這不起作用:

$ openssl ec -pubin -inform der -in public.der -text -noout
read EC key
unable to load Key
140542543959360:error:1012606B:elliptic curve routines:EC_POINT_set_affine_coordinates:point is not on curve:../crypto/ec/ec_lib.c:812:
140542543959360:error:10098010:elliptic curve routines:o2i_ECPublicKey:EC lib:../crypto/ec/ec_asn1.c:1158:
140542543959360:error:100D708E:elliptic curve routines:eckey_pub_decode:decode error:../crypto/ec/ec_ameth.c:157:
140542543959360:error:0B09407D:x509 certificate routines:x509_pubkey_decode:public key decode error:../crypto/x509/x_pubkey.c:125:

此程式碼依賴於這篇文章。如果我使用文章作者給出的 x 和 y 座標作為範例,它會很好地工作:

x = b'\x81\x01\xEC\xE4\x74\x64\xA6\xEA\xD7\x0C\xF6\x9A\x6E\x2B\xD3\xD8\x86\x91\xA3\x26\x2D\x22\xCB\xA4\xF7\x63\x5E\xAF\xF2\x66\x80\xA8'
y = b'\xD8\xA1\x2B\xA6\x1D\x59\x92\x35\xF6\x7D\x9C\xB4\xD5\x8F\x17\x83\xD3\xCA\x43\xE7\x8F\x0A\x5A\xBA\xA6\x24\x07\x99\x36\xC0\xC3\xA9'
scriptPubKey = b'\x04' + x + y
publicKey = bytearray ([0x03, len (scriptPubKey) + 1, 0x00]) + scriptPubKey
algorithmIdentifierId = b'\x06\x07\x2a\x86\x48\xce\x3d\x02\x01'
algorithmIdentifierParameters = b'\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07'
algorithmIdentifier = algorithmIdentifierId + algorithmIdentifierParameters
publicKey = bytearray ([0x30, len (algorithmIdentifier)]) + algorithmIdentifier + publicKey
publicKey = bytearray ([0x30, len (publicKey)]) + publicKey
file = open (f'public.der', 'wb')
file.write (publicKey)
file.close ()

這裡的openssl沒有問題:

$ openssl ec -pubin -inform der -in public.der -text -noout
read EC key
Public-Key: (256 bit)
pub:
   04:81:01:ec:e4:74:64:a6:ea:d7:0c:f6:9a:6e:2b:
   d3:d8:86:91:a3:26:2d:22:cb:a4:f7:63:5e:af:f2:
   66:80:a8:d8:a1:2b:a6:1d:59:92:35:f6:7d:9c:b4:
   d5:8f:17:83:d3:ca:43:e7:8f:0a:5a:ba:a6:24:07:
   99:36:c0:c3:a9
ASN1 OID: prime256v1
NIST CURVE: P-256

有人可以告訴我我錯過了什麼嗎?我試圖反轉 x 和 y 的字節順序,和/或交換 x 和 y,但我無法使用 ScriptPubKey 中的 x 和 y 值…

根據本書的第 73 至 74 頁,x 和 y 應該按此順序給出,並且以大端序…

您的 PEM 文件中有錯誤的橢圓曲線參數。比特幣使用 secp256k1,但您已經(複製)了 NIST P-256(又名 secp256r1)的曲線參數。

algorithmIdentifierParameters應該是b'\x06\x05\x2b\x81\x04\x00\x0a'secp256k1。

引用自:https://bitcoin.stackexchange.com/questions/110881