我使用BouncyCastle创建了椭圆曲线DSA签名的密钥对,并设法使用符合RFC4050的XMLString将公钥导入ECDsaCng。现在我想移动私钥,但没有设法找到解决方案。我最接近的是使用CngKey.Import。
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创建的私钥?
答案 0 :(得分:12)
经过多次拔毛,阅读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();
可以使用Der编码的字节导入密钥来创建CngKey:
var bcKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);
var pkcs8Blob = bcKeyInfo.GetDerEncoded();
var importedKey = CngKey.Import(pkcs8Blob, CngKeyBlobFormat.Pkcs8PrivateBlob);