How do I load an OpenSSL ECDSA key into C#?
我需要将OpenSSL私钥加载到基于C#的应用程序中。
我用来生成密钥的命令是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $ openssl ecparam -name prime256v1 -genkey -noout -out eckey.pem $ openssl ec -in eckey.pem read EC key writing EC key -----BEGIN EC PRIVATE KEY----- MHcCAQEEIMiuwhV+yI0od5E5pSU6ZGuUcflskYD4urONi1g3G7EPoAoGCCqGSM49 AwEHoUQDQgAEe+C/M6u171u5CcL2SQKuFEb+OIEibjw1rx+S5LK4gNNePlDV/bqu Ofjwc5JDqXA07shbfHNIPUn6Hum7qdiUKg== -----END EC PRIVATE KEY----- openssl pkcs8 -topk8 -nocrypt -in eckey.pem -out ec2.pem cat ec2.pem -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgyK7CFX7IjSh3kTml JTpka5Rx+WyRgPi6s42LWDcbsQ+hRANCAAR74L8zq7XvW7kJwvZJAq4URv44gSJu PDWvH5LksriA014+UNX9uq45+PBzkkOpcDTuyFt8c0g9Sfoe6bup2JQq -----END PRIVATE KEY----- |
我正在使用的C#代码
1 2 3 4 | string privKeyPKCS8 = @"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgyK7CFX7IjSh3kTmlJTpka5Rx+WyRgPi6s42LWDcbsQ+hRANCAAR74L8zq7XvW7kJwvZJAq4URv44gSJuPDWvH5LksriA014+UNX9uq45+PBzkkOpcDTuyFt8c0g9Sfoe6bup2JQq"; byte[] privKeyBytes8 = Convert.FromBase64String(privKeyPKCS8);//Encoding.UTF8.GetBytes(privKeyEcc); var pubCNG = CngKey.Import(privKeyBytes, CngKeyBlobFormat.EccPrivateBlob); |
将基于EC的密钥加载到CngKey中的正确方法是什么?
编辑
base 64编码内的密钥遵循以下格式:
1 2 3 4 5 6 | ECPrivateKey ::= SEQUENCE { version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), privateKey OCTET STRING, parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, publicKey [1] BIT STRING OPTIONAL } |
使用secp256r1曲线和未压缩点格式的公钥。
您的密钥PEM / ASCII装甲(页眉,页脚和基数64)使用RFC 5915:椭圆曲线私钥结构中描述的格式进行编码。这是由高效密码学标准组(SECG)首次指定的,这也是命名曲线secp256r1的名称。 Microsoft CNG支持该曲线。
1 2 3 4 5 6 | ECPrivateKey ::= SEQUENCE { version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), privateKey OCTET STRING, parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, publicKey [1] BIT STRING OPTIONAL } |
您首先需要使用(更新的)问题中的命令将此"原始" EC私钥结构转换为PKCS#8结构:
1 | openssl pkcs8 -topk8 -nocrypt -in eckey.pem -out ec2.pem |
要得到:
1 2 3 4 5 6 7 8 9 10 11 | SEQUENCE(3 elem) INTEGER 0 # version of PKCS#8 structure SEQUENCE (2 elem) OBJECT IDENTIFIER 1.2.840.10045.2.1 # it's an EC key) OBJECT IDENTIFIER 1.2.840.10045.3.1.7 # it's secp256r1 OCTET STRING (1 elem) # the key structure SEQUENCE (3 elem) INTEGER 1 # version OCTET STRING (32 byte) # private key value (removed) [1] (1 elem) BIT STRING (520 bit) # public key value (removed) |
最终的结构没有什么不同,您所看到的实际上与初始结构相同。除了PKCS#8结构具有用于指定键类型的对象标识符(OID)和位于曲线前面的OID之外,而您的键之后仅是OID作为参数。两者也都在BIT STRING中携带(可选)公钥值。
因此,解码器识别出此类型并返回EC私钥。
您使用的