如何将基于ECC的X509Certificate2
的公钥/私钥转换为CngKey
和ECDsaCng
一起使用的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
我已成功将上述生成的证书安装到证书存储中。我可以通过指纹来检索它们,但是私钥和公钥的加密提供程序会引发“不支持算法”异常。相反,我知道我应该使用ECDsaCng
和ECDiffieHellmanCng
进行签名/加密。但是这些以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/