Dan*_*ner 15 .net security x509certificate2 cng ecdsa
我怎样才能从基于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
我已成功将上面生成的证书安装到证书库中.我可以通过thumbprint检索它们,但私钥和公钥的加密提供程序抛出"Algorithm not supported"异常.相反,我理解我应该使用ECDsaCng
和ECDiffieHellmanCng
签名/加密.但是这些都是在处理CngKey
.
Bouncy Castle不是一个选项,因为它需要私钥可以导出.
CLR Security将返回一CngKey
对via,GetCngPrivateKey
但它不能与ECDsa一起使用,因为CLRSecurity返回的密钥是ECDH密钥.此外,CLR安全性并没有给我一种方法来从X509Certificate2
签名验证中获取公钥(我甚至没有或者需要签名者的私钥).
有任何想法吗?我在我无计可施......任何帮助会很大赞赏.
小智 6
您需要从证书的公钥创建CngKey:
certificate.PublicKey.EncodedKeyValue.RawData
CngKey包含8个附加字节,前4个字节用于所用曲线的名称(ECS1,ECS3或ECS5),后4个是密钥的长度incl.填充(32,48或66).
将删除证书中公钥的第一个字节(因为ECDSA公钥始终为0x04).
因此,例如对于使用P-256曲线和SHA-256哈希算法的ECDSA,您将获得长度为65字节的公钥.丢弃第一个字节,留下64个字节,然后前缀为4个字节用于曲线,4个字节用于密钥长度,即(Encoding.ASCII):
69(E)
67(C)
83(S)
49(1)
32(密钥长度)
0
0
0
现在你有了公钥(72字节)来创建CngKey:
var cngKey = CngKey.Import([byte array],CngKeyBlobFormat.EccPublicBlob);
var ecdsaCng = new ECDsaCng(cngKey);
您可以验证签名:
return ecdsaCng.VerifyData(encodedBytes,signature);