In .NET there are two P256 curve algorithms that can be used with CngKey:
- CngAlgorithm.ECDiffieHellmanP256 Elliptic Curve Diffie-Hellman (ECDH) key exchange
- CngAlgorithm.ECDsaP256 Elliptic Curve Digital Signature Algorithm (ECDSA)
What confuses me is it appears to be possible to create a signature using CngAlgorithm.ECDiffieHellmanP256
.
Sample code:
// create private key and data
var privateKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
Console.WriteLine($"privateKey: {privateKey.Algorithm} {privateKey.KeyUsage}");
// sign data
var data = new byte[] { 1, 2, 3 };
byte[] signature;
using (var dsa = new ECDsaCng(privateKey))
{
signature = dsa.SignData(data);
Console.WriteLine($"Signature: {Convert.ToBase64String(signature)}");
}
// create stand-alone public key, just to be sure this is working as expected
var publicKeyBlob = privateKey.Export(CngKeyBlobFormat.EccPublicBlob);
var publicKey = CngKey.Import(publicKeyBlob, CngKeyBlobFormat.EccPublicBlob);
Console.WriteLine($"Public key: {publicKey.Algorithm} {publicKey.KeyUsage} {Convert.ToBase64String(publicKeyBlob)}");
// verify signature
using (var dsa = new ECDsaCng(publicKey))
{
var verified = dsa.VerifyData(data, signature);
Console.WriteLine($"Verified: {verified}");
}
output:
privateKey: ECDH_P256 AllUsages
Signature: I1+Bapp8jxC7hUbTQTDTqscR9uoM/bo0OG1WVxgJUWYWq6jmW38a51JnuVRMXMKHosLOClt+AlrjiL/hG7TaqQ==
Public key: ECDH_P256 AllUsages RUNLMSAAAAC9amJDYvEJF+6HXyIhHoOiyUyu3grcH7leeuiOjMAiGbKwFoLssph+NCpY35g2dSHvNgaU11AavV/gAkPH6UPm
Verified: True
Just to show the similarity; if I switch to use CngAlgorithm.ECDsaP256
:
privateKey: ECDSA_P256 AllUsages
Signature: meQ2ywrGWCOnVCaa0bm74Z0Sj37epzSJ5bz/b0x31hGvTn8zk3hcRt5If1+r1PgoR0A1cmSBDF4QUkY0UQjPhw==
Public key: ECDSA_P256 AllUsages RUNTMSAAAADfyG3BtOqGrI63Kh+FPy6V0EmpVX/4mBSbDQ+RxEerlaQCIVq0STrl87D+Re1b+iZ7a8/+S74cHrFNILqYqLXi
Verified: True
Note that doing this the other way around -- trying to create a DH object using a DSA key -- with new ECDiffieHellmanCng(CngKey.Create(CngAlgorithm.ECDsaP256))
results in:
ArgumentException: Keys used with the ECDiffieHellmanCng algorithm must have an algorithm group of ECDiffieHellman.Parameter name: key
This implies there is some kind of difference between the key types.
Is it actually safe to use ECDH keys in this way (eg: is this code generating a secure digital signature)?
Is there a benefit to using ECDSA keys over ECDH keys (other than if you explicitly didn't want to allow key exchange)?