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 (so called magic) are used for the name of the curve used (For ECDsa: ECS1, ECS3 or ECS5, For ECDH: ECK1, ECK3, ECK5), 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.:
var keyData = certificate.PublicKey.EncodedKeyValue.RawData.Skip(1).ToArray();
var keySize = BitConverter.GetBytes(keyData.Length/2);
var magic = Encoding.ASCII.GetBytes("ECS1").Concat()
var eccPublicBlobValue = magic.Concat(keySize).Concat(keyData).ToArray();
Now you have the public key (72 bytes) to create the CngKey from:
var cngKey = CngKey.Import(eccPublicBlobValue, CngKeyBlobFormat.EccPublicBlob);
var ecdsaCng = new ECDsaCng(cngKey);
And you can verify the signature:
return ecdsaCng.VerifyData(encodedBytes, signature);
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…