2017-07-11 221 views
0

我在C#BouncyCastle中生成一個EC密鑰對,並嘗試使用PemWriter將私鑰導出到PEM文件中。這樣做的代碼,以便如下:C#BouncyCastle EC私鑰導出使用PemWriter

var ecKeyPairGenerator = new ECKeyPairGenerator(); 
CKeyGenerationParameters ecKeyGenParams = new ECKeyGenerationParameters(SecObjectIdentifiers.SecP384r1, new SecureRandom()); 
ecKeyPairGenerator.Init(ecKeyGenParams); 
AsymmetricCipherKeyPair pair = ecKeyPairGenerator.GenerateKeyPair(); 

string path = @"c:\tmp\test\myprivkey.pem"; 
TextWriter textWriter = new StreamWriter(path); 
PemWriter pemWriter = new PemWriter(textWriter); 
// passing pair results in the private key being written out 
pemWriter.WriteObject(pair); 
pemWriter.Writer.Flush(); 
pemWriter.Writer.Close(); 

從上面的代碼段輸出的一個例子是:

-----BEGIN EC PRIVATE KEY----- 
MD4CAQEEMJvNXtTUd7A/fY/9/LSXM+Xb/6QS7GydeART/OieN3zh23Uuy0tgiS1D 
rohXMgiPvqAHBgUrgQQAIg== 
-----END EC PRIVATE KEY----- 

然而,使用「的OpenSSL」和相同的EC曲線做同樣的事情時(secp384r1 ),得到的PEM文件是相當不同的,例如,:

openssl ecparam -name secp384r1 -genkey -out mykey2.pem -noout 

-----BEGIN EC PRIVATE KEY----- 
MIGkAgEBBDBqCE9+AWL56cvR2/tRNdyaTIlJnfr6TbhCG+Q48w6yyKR+hE0jkeOV 
7yh1t8NwqT6gBwYFK4EEACKhZANiAAS2uLv7KG6RRBZBOecaxBz8FsMobnxgZkbQ 
8cKdL1DRym1lUDwgfX8AxOC6qkuD1k0UekpHcwiy1mSghy4640qBAKcR3mVghMVF 
77Nm8x6nwNijWZroeqhjrw268PPPuAw= 
-----END EC PRIVATE KEY----- 

正如你所看到的,密鑰長度有很大的不同,我與前創建的P12文件不會被導入到Windows證書ST礦石。我必須在C#BouncyCastle上做錯了什麼,但看不到(查看PemWriter的源代碼以及其他相關類沒有指出任何明顯的錯誤)。

任何幫助將不勝感激。 謝謝。

+0

在檢查BC-生成的私鑰帶有openssl的PEM文件,openssl正確地報告「Private-Key」,「ASN1 OID」和「NIST CURVE」字段,後兩者具有與由openssl生成的PEM文件相同的值。然而,CertUtil無法「轉儲」使用BC生成的私鑰PEM創建的P12文件,同時成功完成了使用由openssl生成的私鑰PEM創建的P12。 – hyongsop

+0

他們可能使用不同asn.1類型的編碼。嘗試在兩個密鑰上運行'openssl asn1parse -i -dump -i key.pem'來檢查。 – mat

+0

@mat是的,我只是這樣做。看起來好像BC PEM文件缺少實際的鍵? openssl PEM文件的ans1parse輸出具有額外的結構,這在BC PEM文件中是缺少的。該結構如下: ** ... 65:d = 1 hl = 2 l = 100 cons:cont [1] 67:d = 2 hl = 2 l = 98 prim:BIT STRING ... * * 此結構位於openssl PEM文件的末尾,導致此結構的文件的其餘部分與BC文件中的相同。我如何找到PEM文件的asn.1類型? – hyongsop

回答

0

事實證明,你可以創建ECPrivateKeyStructure的實例,私人和公共密鑰並保存對象文件的Base64編碼字符串,如,:

... 
int orderBitLength = privKeyParam.Parameters.N.BitLength; 
X962Parameters x962 = new X962Parameters(privKeyParam.PublicKeyParamSet); 
ECPrivateKeyStructure privKeyStruct = 
        new ECPrivateKeyStructure(orderBitLength, privKeyParam.D, pubKeyInfo.PublicKeyData, x962); 

string header = @"-----BEGIN EC PRIVATE KEY-----"; 
string privKeyStr = Convert.ToBase64String(privKeyStruct.GetDerEncoded(), 
        Base64FormattingOptions.InsertLineBreaks); 
string tail = @"-----END EC PRIVATE KEY-----"; 

string path = @"c:\tmp\myprivkey.pem"; 
TextWriter textWriter = new StreamWriter(path); 
textWriter.WriteLine(header); 
textWriter.WriteLine(privKeyStr); 
textWriter.WriteLine(tail); 
textWriter.Flush(); 
textWriter.Close(); 
... 
相關問題