我正在使用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将通过GetCngPrivateKey给我一个CngKey对,但不能与ECDsa一起使用,因为CLRSecurity返回的密钥是ECDH密钥.此外,CLR Security还没有给我一种从X509Certificate2获取公开密钥进行签名验证的方法(我甚至没有或需要签名者的私钥).
有任何想法吗?我在我的智慧结束…任何帮助将不胜感激.
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 (E)
67 (C)
83 (S)
49 (1)
32 (Key length)
0
0
0
现在你有公共密钥(72字节)创建CngKey从:
var cngKey = CngKey.Import([the byte array],CngKeyBlobFormat.EccpublicBlob);
var ecdsaCng = new ECDsaCng(cngKey);
你可以验证签名:
return ecdsaCng.VerifyData(encodedBytes,signature);