How can I get the public/private keys from an ECC-based X509Certificate2
\'s into CngKey
\'s for use with ECDsaCng
and ECDiffieHel
You need to create the CngKey from the public key of the certificate:
certificate.PublicKey.EncodedKeyValue.RawData
The CngKey contains 8 additional bytes, the first 4 bytes are used for the name of the curve used (ECS1, ECS3 or ECS5), the last 4 are the length of the key incl. padding (32, 48 or 66).
The first byte of the public key from the certificate is removed (as it is always 0x04 for ECDSA public key).
So for instance for ECDSA using P-256 curve and SHA-256 hash algorithm, you will get a public key of length 65 bytes. Discard the first byte, leaving 64 bytes, then prefix with 4 bytes for curve and 4 bytes for key length i.e. (Encoding.ASCII):
69 (E)
67 (C)
83 (S)
49 (1)
32 (Key length)
0
0
0
Now you have the public key (72 bytes) to create the CngKey from:
var cngKey = CngKey.Import([the byte array], CngKeyBlobFormat.EccPublicBlob);
var ecdsaCng = new ECDsaCng(cngKey);
And you can verify the signature:
return ecdsaCng.VerifyData(encodedBytes, signature);