Public-Key

將原始 ECC 私鑰轉換為 ASN.1 DER 編碼密鑰

  • April 26, 2020

我創建了一個 32 字節的隨機整數數組,用作我的secp256k1曲線私鑰。

const uint8_t secret[] = {0xb2,0x9a,0xc6,0xbd,0xc7,0x3d,0xc4,0xe1,
                         0x85,0xa7,0x3c,0x96,0xf8,0x1c,0x58,0x43,
                         0xe2,0xbf,0x2d,0x68,0xe5,0x6f,0xf6,0xae,
                         0x4f,0xe7,0x51,0xcd,0x9d,0x47,0x00,0xfa}

我想將此十六進制數組轉換為ASN.1 DER編碼的密鑰,以便我可以進一步將它與我的硬體一起使用,該硬體期望密鑰是ASN.1 DER編碼的。

你能指出我如何實現這一目標的正確方向嗎?

編輯,我找到了一個編碼的密鑰對,也許我可以從中獲取。下面的數組是否包含公鑰和私鑰部分?

keyPairData[] = { 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13,
   0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02,
   0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
   0x03, 0x01, 0x07, 0x04, 0x6D, 0x30, 0x6B, 0x02,
   0x01, 0x01, 0x04, 0x20, 0x78, 0xE5, 0x20, 0x6A,
   0x08, 0xED, 0xD2, 0x52, 0x36, 0x33, 0x8A, 0x24,
   0x84, 0xE4, 0x2F, 0x1F, 0x7D, 0x1F, 0x6D, 0x94,
   0x37, 0xA9, 0x95, 0x86, 0xDA, 0xFC, 0xD2, 0x23,
   0x6F, 0xA2, 0x87, 0x35, 0xA1, 0x44, 0x03, 0x42,
   0x00, 0x04, 0xED, 0xA7, 0xE9, 0x0B, 0xF9, 0x20,
   0xCF, 0xFB, 0x9D, 0xF6, 0xDB, 0xCE, 0xF7, 0x20,
   0xE1, 0x23, 0x8B, 0x3C, 0xEE, 0x84, 0x86, 0xD2,
   0x50, 0xE4, 0xDF, 0x30, 0x11, 0x50, 0x1A, 0x15,
   0x08, 0xA6, 0x2E, 0xD7, 0x49, 0x52, 0x78, 0x63,
   0x6E, 0x61, 0xE8, 0x5F, 0xED, 0xB0, 0x6D, 0x87,
   0x92, 0x0A, 0x04, 0x19, 0x14, 0xFE, 0x76, 0x63,
   0x55, 0xDF, 0xBD, 0x68, 0x61, 0x59, 0x31, 0x8E,
   0x68, 0x7C };

ASN.1 是一種定義資料結構的方法,DER 是這些結構的二進制編碼。但他們自己並沒有描述任何結構。說某些東西需要進行 ASN.1 / DER 編碼就像說需要在 XML 中表示密鑰而不指定標籤或樹結構。


您需要生成的是 PKCS#8(內部)編碼的私鑰。我之前提供的SEC1 文件連結在其中定義了內部SEQUENCE。PKCS#8 內部結構用於辨識密鑰的類型。SEC1 中的大部分內容已復製到 X9.62。是的,它顯然包含可選的公鑰。如果您尋找將您的私鑰編碼為 PKCS#8 的方法,您會發現更多資訊。例如,它是 OpenSSL 的預設編碼,但大多數其他庫將使用相同的編碼。

我可以在 Java 中生成相同的(ECPrivateKey.getEncoded()用於曲線"secp256k1"),但不包括可選的 - 在我看來是虛假的 - 公共點。您可以在 Lapo 線上 ASN.1 解碼器中看到您提供的結構。是的,它清楚地將公鑰作為可選的 BIT STRING 包含在末尾(自己附加它意味著調整序列的長度編碼)。

如果您的結構缺少公鑰,我會首先嘗試導入它;從私鑰和參數計算公鑰非常容易:只需將點與基點 G 相乘。設備可能能夠做到這一點。


您通常希望創建一個“命名”曲線,其中域參數由 OID 給出(如您給出的範例中所示)。僅在有限的一組曲線上執行的設備更有可能拒絕顯式域參數。

但是,我遇到了要求您提供未命名參數的 HSM。在這種情況下,您可能需要使用顯式參數構造您的私鑰,然後編碼…

引用自:https://crypto.stackexchange.com/questions/80275