ECDsaCng是使用Windows CNG的ECDSA實現。它特定於Windows,因此在Linux上不受支持。
跨平臺的方式做到這將是
using (ECDsa ecdsa = ECDsa.Create())
{
ecdsa.ImportParameters(Pkcs8ToParameters(privateKey));
// the stuff in your current using
}
當然,PKCS#8爲ECParameters是不是世界上最容易的事情。但我們可以放棄它。在another answer中,有一個爲RSA構建PKCS#8的細節。
讓我們這個斑點:
308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B02
0101042070A12C2DB16845ED56FF68CFC21A472B3F04D7D6851BF6349F2D7D5B
3452B38AA144034200048101ECE47464A6EAD70CF69A6E2BD3D88691A3262D22
CBA4F7635EAFF26680A8D8A12BA61D599235F67D9CB4D58F1783D3CA43E78F0A
5ABAA624079936C0C3A9
它打破了像
30 /* SEQUENCE */
81 87 (payload is 0x87 bytes)
02 /* INTEGER */ 01 (1 byte) 00 // Integer: 0. // validate this
30 /* SEQUENCE */ 13 (0x13 bytes)
06 /* OBJECT IDENTIFIER */ 07 (7 bytes)
2A8648CE3D0201 (1.2.840.10045.2.1/ecPublicKey) // validate this
06 /* OBJECT IDENTIFIER */ 08 (8 bytes)
2A8648CE3D030107 (1.2.840.10045.3.1.7/secp256r1) // save this, curveName
04 /* OCTET STREAM (byte[]) */ 6D (0x6D bytes)
// Since the constructed (0x20) bit isn't set in the tag normally we stop here,
// but we know from the ecPublicKey context that this is also DER data.
30 /* SEQUENCE */ 6B (0x6B bytes)
02 /* Integer */ 01 (1 byte) 01 // Integer: 1. // validate this.
04 /* OCTET STREAM (byte[]) */ 20 (0x20 bytes/256 bits)
70A12C2DB16845ED56FF68CFC21A472B3F04D7D6851BF6349F2D7D5B3452B38A // save this: D
A1 /* CONSTRUCTED CONTEXT SPECIFIC 1 */ 44 (0x44 bytes)
03 /* BIT STRING (byte[] if the first byte is 0x00) */ 66 (0x66 bytes)
00 // Oh, good, it's a normal byte[]. Validate this.
// Formatting will become apparent. Save this.
04
8101ECE47464A6EAD70CF69A6E2BD3D88691A3262D22CBA4F7635EAFF26680A8
D8A12BA61D599235F67D9CB4D58F1783D3CA43E78F0A5ABAA624079936C0C3A9
末比特串 「公鑰」。由於它始於04
(通常情況下,除非發件人對你生氣),它代表一個「未壓縮點」,這意味着左邊的前半部分是X座標,其餘部分是Y座標。所以從這個結構中你可能會得到這樣的
string curveOid;
// You can decode the OID, or special case it.
switch (curveName)
{
case "2A8648CE3D030107":
// secp256r1
curveOid = "1.2.840.10045.3.1.7";
break;
case "2B81040022"
// secp384r1
curveOid = "1.3.132.0.34";
break;
case "2B81040023":
// secp521r1
curveOid = "1.3.132.0.35";
break;
default:
throw new InvalidOperationException();
}
return new ECParameters
{
Curve = ECCurve.CreateFromValid(curveOid),
// We saved this.
D = d,
Q = new ECPoint
{
X = x,
Y = y
},
}
這發生在D1部分的Suite B Implementer’s Guide to FIPS 186-3 (ECDSA)(NIST P-256/secp256r1)所使用的密鑰。
由於EC密鑰格式在INTEGER值(可能需要填充字節)上很短,您可以爲您想要支持的每個密鑰大小構建一個手動提取器。或者你可以去現場DER閱讀路線。或者您可以嘗試讓您的私鑰以更友好的形式序列化,以供您的應用程序使用。