如何将基于ECC的X509Certificate2
中的公钥/私钥转换为CngKey
,以便与ECDsaCng
和{{1}一起使用}}?
我目前正在使用RSA 2048位密钥对来签名/加密内容。我是通过从安全存储的ECDiffieHellmanCng
中提取证书并使用标记为不可导出的私钥来实现此目的的。我想将当前实现转换为使用ECDSA和ECDH,以便我可以使用较小的密钥大小来获得同等的安全性。
我已经使用openssl成功生成了ECC证书:
X509Store
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
的交易。
Bouncy Castle不是一个选项,因为它需要私钥可以导出。
CLR Security会通过CngKey
返回CngKey
对,但不能与ECDsa一起使用,因为CLRSecurity返回的密钥是ECDH密钥。此外,CLR安全无法为我提供从GetCngPrivateKey
获取签名验证的公钥的方法(我甚至不需要签名者的私钥)。
有什么想法吗?我的智慧结束了......任何帮助都会得到很多赞赏。
答案 0 :(得分:6)
您需要从证书的公钥创建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(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);
您可以验证签名:
返回ecdsaCng.VerifyData(encodedBytes,signature);