2

我使用 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 创建的私钥?

4

1 回答 1

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);
于 2012-02-24T14:08:15.140 回答