如何将基于ECC的X509Certificate2的公钥/私钥转换为CngKeyECDsaCng一起使用的ECDiffieHellmanCng

我目前正在使用RSA 2048位密钥对来签名/加密内容。我是通过从X509Store提取证书的方式来实现的,这些证书使用标记为不可导出的私钥安全地存储在这些证书中。我想将当前实现转换为使用ECDSA和ECDH,以便可以使用较小的密钥来实现等效的安全性。

我已经使用openssl成功生成了ECC证书:


openssl ecparam -out private.pem -name prime256v1 -genkey
openssl req -new -key private.pem -x509 -nodes -days 365 -out public.cer
openssl pkcs12 -export -in public.cer -inkey private.pem -out export.pfx


我已成功将上述生成的证书安装到证书存储中。我可以通过指纹来检索它们,但是私钥和公钥的加密提供程序会引发“不支持算法”异常。相反,我知道我应该使用ECDsaCngECDiffieHellmanCng进行签名/加密。但是这些以CngKey处理。

Bouncy Castle不是一个选择,因为它要求私钥是可导出的。

CLR Security将通过CngKey返回给我GetCngPrivateKey对,但是不能与ECDsa一起使用,因为CLRSecurity返回的密钥是ECDH密钥。此外,CLR安全性没有给我提供从X509Certificate2仅获取公钥进行签名验证的方法(我什至没有或不需要签名者的私钥)。

有任何想法吗?我不知所措...任何帮助将不胜感激。

最佳答案

您需要根据证书的公钥创建CngKey:


certificate.PublicKey.EncodedKeyValue.RawData


CngKey包含8个附加字节,前4个字节用于所用曲线的名称(ECS1,ECS3或ECS5),后4个是密钥的长度,包括。填充(32、48或66)。

从证书中删除公钥的第一个字节(因为对于ECDSA公钥,它始终为0x04)。

因此,例如对于使用P-256曲线和SHA-256哈希算法的ECDSA,您将获得长度为65个字节的公共密钥。舍弃第一个字节,保留64个字节,然后为曲线添加4个字节并为键长添加4个字节的前缀,即(Encoding.ASCII):


69(东)

67(摄氏度)

83(南)

49(1)

32(密钥长度)

0

0

0


现在,您具有公共密钥(72个字节)可以从以下位置创建CngKey:


var cngKey = CngKey.Import([字节数组],CngKeyBlobFormat.EccPublicBlob);

var ecdsaCng = new ECDsaCng(cngKey);


您可以验证签名:


返回ecdsaCng.VerifyData(encodedBytes,签名);

关于.net - 从Windows证书存储区将基于ECC的证书导入CngKey,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22762380/

10-13 06:01