2012-02-23 99 views
2

我已经使用BouncyCastle为椭圆曲线DSA签名创建了密钥对,并使用XMLString根据RFC4050设法将公钥导入ECDsaCng。现在我想要移动私钥并且没有设法找到解决方案。我得到的最接近的是使用CngKey.Import。从BouncyCastle导出EC私钥并导入到CngKey或ECDsaCng中?

CngKey.Import支持PKCS#8格式,所以如果你可以把你的密钥变成有效的pkcs8,那么它应该可以工作。不幸的是,下面的代码不起作用。

var privatekey = (ECPrivateKeyParameters) keyPair.Private; 

var pkinfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privatekey); 

byte[] pkcs8Blob = pkinfo.GetDerEncoded(); 

var importedKey = CngKey.Import(pkcs8Blob, CngKeyBlobFormat.Pkcs8PrivateBlob); 

这将引发异常:

System.Security.Cryptography.CryptographicException:满足ASN1坏标记值。

GetDerEncoded应该返回一个有效的Pkcs8 blob,据我所知。

如何使用在ECDsaCng对象中使用BouncyCastle创建的私钥?

回答

11

经过多次拉动,阅读RFC和研究由BouncyCastle和CngKey.Export生成的字节数组,我找到了答案。

问题在于BouncyCastle如何将EC密钥编码为DER/Pkcs8格式。与这个特定问题相关的两个RFC是RFC5915(这不是一个标准,而是一个共识文档)和RFC5480。他们声明曲线参数必须使用RFC5480中引用的命名曲线来指定。在使用错误的生成器参数创建AsymmetricCipherKeyPair时,PKCS8/DER导出的BouncyCastle实现会导出不符合这两个规范的整个曲线规范(隐式曲线)。您必须使用指定命名曲线的ECKeyGenerationParameters。

在BouncyCastle的创建可互操作的密钥时,必须使用(据我可以告诉)以下:

string namedCurve = "prime256v1"; 
ECKeyPairGenerator pGen = new ECKeyPairGenerator(); 
ECKeyGenerationParameters genParam = new ECKeyGenerationParameters(
    X962NamedCurves.GetOid(namedCurve) 
    new SecureRandom()); 
pGen.Init(genParam); 

AsymmetricCipherKeyPair keyPair = pGen.GenerateKeyPair(); 

的CngKey可以通过导入使用DER编码字节密钥来创建的:

var bcKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private); 
var pkcs8Blob = bcKeyInfo.GetDerEncoded(); 
var importedKey = CngKey.Import(pkcs8Blob, CngKeyBlobFormat.Pkcs8PrivateBlob);