ECDiffieHellmanCng Class

Definition

Provides a Cryptography Next Generation (CNG) implementation of the Elliptic Curve Diffie-Hellman (ECDH) algorithm. This class is used to perform cryptographic operations.

public ref class ECDiffieHellmanCng sealed : System::Security::Cryptography::ECDiffieHellman
public sealed class ECDiffieHellmanCng : System.Security.Cryptography.ECDiffieHellman
type ECDiffieHellmanCng = class
    inherit ECDiffieHellman
Public NotInheritable Class ECDiffieHellmanCng
Inherits ECDiffieHellman
Inheritance
Inheritance

Examples

The following example shows how to use the ECDiffieHellmanCng class to establish a key exchange and how to use that key to encrypt a message that can be sent over a public channel and decrypted by the receiver.

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

class Alice
{
    public static byte[] alicePublicKey;

    public static void Main(string[] args)
    {
        using (ECDiffieHellmanCng alice = new ECDiffieHellmanCng())
        {

            alice.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
            alice.HashAlgorithm = CngAlgorithm.Sha256;
            alicePublicKey = alice.PublicKey.ToByteArray();
            Bob bob = new Bob();
            CngKey bobKey = CngKey.Import(bob.bobPublicKey, CngKeyBlobFormat.EccPublicBlob);
            byte[] aliceKey = alice.DeriveKeyMaterial(bobKey);
            byte[] encryptedMessage = null;
            byte[] iv = null;
            Send(aliceKey, "Secret message", out encryptedMessage, out iv);
            bob.Receive(encryptedMessage, iv);
        }
    }

    private static void Send(byte[] key, string secretMessage, out byte[] encryptedMessage, out byte[] iv)
    {
        using (Aes aes = new AesCryptoServiceProvider())
        {
            aes.Key = key;
            iv = aes.IV;

            // Encrypt the message
            using (MemoryStream ciphertext = new MemoryStream())
            using (CryptoStream cs = new CryptoStream(ciphertext, aes.CreateEncryptor(), CryptoStreamMode.Write))
            {
                byte[] plaintextMessage = Encoding.UTF8.GetBytes(secretMessage);
                cs.Write(plaintextMessage, 0, plaintextMessage.Length);
                cs.Close();
                encryptedMessage = ciphertext.ToArray();
            }
        }
    }
}
public class Bob
{
    public byte[] bobPublicKey;
    private byte[] bobKey;
    public Bob()
    {
        using (ECDiffieHellmanCng bob = new ECDiffieHellmanCng())
        {

            bob.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
            bob.HashAlgorithm = CngAlgorithm.Sha256;
            bobPublicKey = bob.PublicKey.ToByteArray();
            bobKey = bob.DeriveKeyMaterial(CngKey.Import(Alice.alicePublicKey, CngKeyBlobFormat.EccPublicBlob));
        }
    }

    public void Receive(byte[] encryptedMessage, byte[] iv)
    {

        using (Aes aes = new AesCryptoServiceProvider())
        {
            aes.Key = bobKey;
            aes.IV = iv;
            // Decrypt the message
            using (MemoryStream plaintext = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(plaintext, aes.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(encryptedMessage, 0, encryptedMessage.Length);
                    cs.Close();
                    string message = Encoding.UTF8.GetString(plaintext.ToArray());
                    Console.WriteLine(message);
                }
            }
        }
    }
}
Imports System.IO
Imports System.Security.Cryptography
Imports System.Text




Class Alice
    Public Shared alicePublicKey() As Byte


    Public Shared Sub Main(ByVal args() As String)
        Using alice As New ECDiffieHellmanCng()
            alice.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash
            alice.HashAlgorithm = CngAlgorithm.Sha256
            alicePublicKey = alice.PublicKey.ToByteArray()
            Dim bob As New Bob()
            Dim k As CngKey = CngKey.Import(bob.bobPublicKey, CngKeyBlobFormat.EccPublicBlob)
            Dim aliceKey As Byte() = alice.DeriveKeyMaterial(CngKey.Import(bob.bobPublicKey, CngKeyBlobFormat.EccPublicBlob))
            Dim encryptedMessage As Byte() = Nothing
            Dim iv As Byte() = Nothing
            Send(aliceKey, "Secret message", encryptedMessage, iv)
            bob.Receive(encryptedMessage, iv)
        End Using
    End Sub


    Private Shared Sub Send(ByVal key() As Byte, ByVal secretMessage As String, ByRef encryptedMessage() As Byte, ByRef iv() As Byte)
        Using aes As New AesCryptoServiceProvider()
            aes.Key = key
            iv = aes.IV

            ' Encrypt the message
            Using ciphertext As New MemoryStream()
                Using cs As New CryptoStream(ciphertext, aes.CreateEncryptor(), CryptoStreamMode.Write)
                    Dim plaintextMessage As Byte() = Encoding.UTF8.GetBytes(secretMessage)
                    cs.Write(plaintextMessage, 0, plaintextMessage.Length)
                    cs.Close()
                    encryptedMessage = ciphertext.ToArray()
                End Using
            End Using
        End Using

    End Sub
End Class

Public Class Bob
    Public bobPublicKey() As Byte
    Private bobKey() As Byte

    Public Sub New()
        Using bob As New ECDiffieHellmanCng()

            bob.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash
            bob.HashAlgorithm = CngAlgorithm.Sha256
            bobPublicKey = bob.PublicKey.ToByteArray()
            bobKey = bob.DeriveKeyMaterial(CngKey.Import(Alice.alicePublicKey, CngKeyBlobFormat.EccPublicBlob))
        End Using

    End Sub


    Public Sub Receive(ByVal encryptedMessage() As Byte, ByVal iv() As Byte)

        Using aes As New AesCryptoServiceProvider()
                aes.Key = bobKey
                aes.IV = iv
                ' Decrypt the message
            Using plaintext As New MemoryStream()
                Using cs As New CryptoStream(plaintext, aes.CreateDecryptor(), CryptoStreamMode.Write)
                    cs.Write(encryptedMessage, 0, encryptedMessage.Length)
                    cs.Close()
                    Dim message As String = Encoding.UTF8.GetString(plaintext.ToArray())
                    Console.WriteLine(message)
                End Using
            End Using
        End Using
    End Sub
End Class

Remarks

The ECDiffieHellmanCng class enables two parties to exchange private key material even if they are communicating through a public channel. Both parties can calculate the same secret value, which is referred to as the secret agreement in the managed Diffie-Hellman classes. The secret agreement can then be used for a variety of purposes, including as a symmetric key. However, instead of exposing the secret agreement directly, the ECDiffieHellmanCng class does some post-processing on the agreement before providing the value. This post processing is referred to as the key derivation function (KDF); you can select which KDF you want to use and set its parameters through a set of properties on the instance of the Diffie-Hellman object.

Key derivation function Properties
Hash HashAlgorithm - The hash algorithm that is used to process the secret agreement.

SecretPrepend - An optional byte array to prepend to the secret agreement before hashing it.

SecretAppend - An optional byte array to append to the secret agreement before hashing it.
Hmac HashAlgorithm - The hash algorithm that is used to process the secret agreement.

SecretPrepend- An optional byte array to prepend to the secret agreement before hashing it.

SecretAppend - An optional byte array to append to the secret agreement before hashing it.
Tls Label - The label for key derivation.

Seed - The seed for key derivation.

The result of passing the secret agreement through the key derivation function is a byte array that may be used as key material for your application. The number of bytes of key material generated is dependent on the key derivation function; for example, SHA-256 will generate 256 bits of key material, whereas SHA-512 will generate 512 bits of key material. The basic flow of an ECDH key exchange is as follows:

  1. Alice and Bob create a key pair to use for the Diffie-Hellman key exchange operation

  2. Alice and Bob configure the KDF using parameters the agree on.

  3. Alice sends Bob her public key.

  4. Bob sends Alice his public key.

  5. Alice and Bob use each other's public keys to generate the secret agreement, and apply the KDF to the secret agreement to generate key material.

Constructors

ECDiffieHellmanCng()

Initializes a new instance of the ECDiffieHellmanCng class with a random key pair.

ECDiffieHellmanCng(CngKey)

Initializes a new instance of the ECDiffieHellmanCng class by using the specified CngKey object.

ECDiffieHellmanCng(ECCurve)

Creates a new instance of the ECDiffieHellmanCng class whose public/private key pair is generated over the specified curve.

ECDiffieHellmanCng(Int32)

Initializes a new instance of the ECDiffieHellmanCng class with a random key pair, using the specified key size.

Fields

KeySizeValue

Represents the size, in bits, of the key modulus used by the asymmetric algorithm.

(Inherited from AsymmetricAlgorithm)
LegalKeySizesValue

Specifies the key sizes that are supported by the asymmetric algorithm.

(Inherited from AsymmetricAlgorithm)

Properties

HashAlgorithm

Gets or sets the hash algorithm to use when generating key material.

HmacKey

Gets or sets the Hash-based Message Authentication Code (HMAC) key to use when deriving key material.

Key

Specifies the CngKey that is used by the current object for cryptographic operations.

KeyDerivationFunction

Gets or sets the key derivation function for the ECDiffieHellmanCng class.

KeyExchangeAlgorithm

Gets the name of the key exchange algorithm.

(Inherited from ECDiffieHellman)
KeySize

Gets or sets the size, in bits, of the key modulus used by the asymmetric algorithm.

KeySize

Gets or sets the size, in bits, of the key modulus used by the asymmetric algorithm.

(Inherited from AsymmetricAlgorithm)
Label

Gets or sets the label value that is used for key derivation.

LegalKeySizes

Gets the key sizes that are supported by the asymmetric algorithm.

LegalKeySizes

Gets the key sizes that are supported by the asymmetric algorithm.

(Inherited from AsymmetricAlgorithm)
PublicKey

Gets the public key that can be used by another ECDiffieHellmanCng object to generate a shared secret agreement.

SecretAppend

Gets or sets a value that will be appended to the secret agreement when generating key material.

SecretPrepend

Gets or sets a value that will be added to the beginning of the secret agreement when deriving key material.

Seed

Gets or sets the seed value that will be used when deriving key material.

SignatureAlgorithm

Gets the name of the signature algorithm.

(Inherited from ECDiffieHellman)
UseSecretAgreementAsHmacKey

Gets a value that indicates whether the secret agreement is used as a Hash-based Message Authentication Code (HMAC) key to derive key material.

Methods

Clear()

Releases all resources used by the AsymmetricAlgorithm class.

(Inherited from AsymmetricAlgorithm)
DeriveKeyFromHash(ECDiffieHellmanPublicKey, HashAlgorithmName)

Performs key derivation using a specified hash algorithm.

(Inherited from ECDiffieHellman)
DeriveKeyFromHash(ECDiffieHellmanPublicKey, HashAlgorithmName, Byte[], Byte[])

Performs key derivation using a specified hash algorithm with optional prepended or appended data.

DeriveKeyFromHash(ECDiffieHellmanPublicKey, HashAlgorithmName, Byte[], Byte[])

When implemented in a derived class, performs key derivation using a specified hash algorithm with optional prepended or appended data.

(Inherited from ECDiffieHellman)
DeriveKeyFromHmac(ECDiffieHellmanPublicKey, HashAlgorithmName, Byte[])

Performs key derivation using a specified HMAC (Hash-based Message Authentication Code) algorithm.

(Inherited from ECDiffieHellman)
DeriveKeyFromHmac(ECDiffieHellmanPublicKey, HashAlgorithmName, Byte[], Byte[], Byte[])

Performs key derivation using a specified HMAC (Hash-based Message Authentication Code) algorithm with optional prepended or appended data.

DeriveKeyFromHmac(ECDiffieHellmanPublicKey, HashAlgorithmName, Byte[], Byte[], Byte[])

When implemented in a derived class, performs key derivation using a specified HMAC (Hash-based Message Authentication Code) algorithm with optional prepended or appended data.

(Inherited from ECDiffieHellman)
DeriveKeyMaterial(CngKey)

Derives the key material that is generated from the secret agreement between two parties, given a CngKey object that contains the second party's public key.

DeriveKeyMaterial(ECDiffieHellmanPublicKey)

Derives the key material that is generated from the secret agreement between two parties, given an ECDiffieHellmanPublicKey object that contains the second party's public key.

DeriveKeyTls(ECDiffieHellmanPublicKey, Byte[], Byte[])

Performs key derivation using the TLS (Transport Layer Security) 1.1 PRF (Pseudo-Random Function).

DeriveKeyTls(ECDiffieHellmanPublicKey, Byte[], Byte[])

When implemented in a derived class, performs key derivation using the TLS (Transport Layer Security) 1.1 PRF (Pseudo-Random Function).

(Inherited from ECDiffieHellman)
DeriveRawSecretAgreement(ECDiffieHellmanPublicKey)

Derive raw key material.

(Inherited from ECDiffieHellman)
DeriveSecretAgreementHandle(CngKey)

Gets a handle to the secret agreement generated between two parties, given a CngKey object that contains the second party's public key.

DeriveSecretAgreementHandle(ECDiffieHellmanPublicKey)

Gets a handle to the secret agreement generated between two parties, given an ECDiffieHellmanPublicKey object that contains the second party's public key.

Dispose()

Releases all resources used by the current instance of the AsymmetricAlgorithm class.

(Inherited from AsymmetricAlgorithm)
Dispose(Boolean)

Releases the unmanaged resources used by the AsymmetricAlgorithm class and optionally releases the managed resources.

(Inherited from AsymmetricAlgorithm)
Equals(Object)

Determines whether the specified object is equal to the current object.

(Inherited from Object)
ExportECPrivateKey()

Exports the current key in the ECPrivateKey format.

(Inherited from ECDiffieHellman)
ExportECPrivateKeyPem()

Exports the current key in the ECPrivateKey format, PEM encoded.

(Inherited from ECAlgorithm)
ExportEncryptedPkcs8PrivateKey(ReadOnlySpan<Byte>, PbeParameters)

Exports the current key in the PKCS#8 EncryptedPrivateKeyInfo format with a byte-based password.

ExportEncryptedPkcs8PrivateKey(ReadOnlySpan<Byte>, PbeParameters)

Exports the current key in the PKCS#8 EncryptedPrivateKeyInfo format with a byte-based password.

(Inherited from AsymmetricAlgorithm)
ExportEncryptedPkcs8PrivateKey(ReadOnlySpan<Char>, PbeParameters)

Exports the current key in the PKCS#8 EncryptedPrivateKeyInfo format with a char-based password.

ExportEncryptedPkcs8PrivateKey(ReadOnlySpan<Char>, PbeParameters)

Exports the current key in the PKCS#8 EncryptedPrivateKeyInfo format with a char-based password.

(Inherited from AsymmetricAlgorithm)
ExportEncryptedPkcs8PrivateKeyPem(ReadOnlySpan<Byte>, PbeParameters)

Exports the current key in the PKCS#8 EncryptedPrivateKeyInfo format with a byte-based password, PEM encoded.

(Inherited from AsymmetricAlgorithm)
ExportEncryptedPkcs8PrivateKeyPem(ReadOnlySpan<Char>, PbeParameters)

Exports the current key in the PKCS#8 EncryptedPrivateKeyInfo format with a char-based password, PEM encoded.

(Inherited from AsymmetricAlgorithm)
ExportExplicitParameters(Boolean)

Exports the key and explicit curve parameters used by the ECCurve object into an ECParameters object.

ExportExplicitParameters(Boolean)

When overridden in a derived class, exports either the public or the public and private key information using the explicit curve form from a working ECDiffieHellman key to an ECParameters structure so that it can be passed to the ImportParameters(ECParameters) method.

(Inherited from ECDiffieHellman)
ExportParameters(Boolean)

Exports the key used by the ECCurve object into an ECParameters object.

ExportParameters(Boolean)

When overridden in a derived class, exports either the public or the public and private key information from a working ECDiffieHellman key to an ECParameters structure so that it can be passed to the ImportParameters(ECParameters) method.

(Inherited from ECDiffieHellman)
ExportPkcs8PrivateKey()

Exports the current key in the PKCS#8 PrivateKeyInfo format.

(Inherited from AsymmetricAlgorithm)
ExportPkcs8PrivateKeyPem()

Exports the current key in the PKCS#8 PrivateKeyInfo format, PEM encoded.

(Inherited from AsymmetricAlgorithm)
ExportSubjectPublicKeyInfo()

Exports the public-key portion of the current key in the X.509 SubjectPublicKeyInfo format.

(Inherited from AsymmetricAlgorithm)
ExportSubjectPublicKeyInfoPem()

Exports the public-key portion of the current key in the X.509 SubjectPublicKeyInfo format, PEM encoded.

(Inherited from AsymmetricAlgorithm)
FromXmlString(String)

This method is not implemented.

FromXmlString(String)

This method throws in all cases.

(Inherited from ECDiffieHellman)
FromXmlString(String, ECKeyXmlFormat)
Obsolete.

Deserializes the key information from an XML string by using the specified format.

GenerateKey(ECCurve)

Generates a new ephemeral public/private key pair for the specified curve.

GenerateKey(ECCurve)

When overridden in a derived class, generates a new ephemeral public/private key pair for the specified curve.

(Inherited from ECDiffieHellman)
GetHashCode()

Serves as the default hash function.

(Inherited from Object)
GetType()

Gets the Type of the current instance.

(Inherited from Object)
ImportECPrivateKey(ReadOnlySpan<Byte>, Int32)

Imports the public/private keypair from an ECPrivateKey structure, replacing the keys for this object.

(Inherited from ECDiffieHellman)
ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<Byte>, ReadOnlySpan<Byte>, Int32)

Imports the public/private keypair from a PKCS#8 EncryptedPrivateKeyInfo structure after decrypting with a byte-based password, replacing the keys for this object.

ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<Byte>, ReadOnlySpan<Byte>, Int32)

Imports the public/private keypair from a PKCS#8 EncryptedPrivateKeyInfo structure after decrypting with a byte-based password, replacing the keys for this object.

(Inherited from ECDiffieHellman)
ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<Char>, ReadOnlySpan<Byte>, Int32)

Imports the public/private keypair from a PKCS#8 EncryptedPrivateKeyInfo structure after decrypting with a char-based password, replacing the keys for this object.

ImportEncryptedPkcs8PrivateKey(ReadOnlySpan<Char>, ReadOnlySpan<Byte>, Int32)

Imports the public/private keypair from a PKCS#8 EncryptedPrivateKeyInfo structure after decrypting with a char-based password, replacing the keys for this object.

(Inherited from ECDiffieHellman)
ImportFromEncryptedPem(ReadOnlySpan<Char>, ReadOnlySpan<Byte>)

Imports an encrypted RFC 7468 PEM-encoded private key, replacing the keys for this object.

(Inherited from ECDiffieHellman)
ImportFromEncryptedPem(ReadOnlySpan<Char>, ReadOnlySpan<Char>)

Imports an encrypted RFC 7468 PEM-encoded private key, replacing the keys for this object.

(Inherited from ECDiffieHellman)
ImportFromPem(ReadOnlySpan<Char>)

Imports an RFC 7468 PEM-encoded key, replacing the keys for this object.

(Inherited from ECDiffieHellman)
ImportParameters(ECParameters)

Imports the specified parameters for an ECCurve object as a key into the current instance.

ImportParameters(ECParameters)

When overridden in a derived class, imports the specified parameters for an ECCurve as an ephemeral key into the current ECDiffieHellman object.

(Inherited from ECDiffieHellman)
ImportPkcs8PrivateKey(ReadOnlySpan<Byte>, Int32)

Imports the public/private keypair from a PKCS#8 PrivateKeyInfo structure after decryption, replacing the keys for this object.

ImportPkcs8PrivateKey(ReadOnlySpan<Byte>, Int32)

Imports the public/private keypair from a PKCS#8 PrivateKeyInfo structure after decryption, replacing the keys for this object.

(Inherited from ECDiffieHellman)
ImportSubjectPublicKeyInfo(ReadOnlySpan<Byte>, Int32)

Imports the public key from an X.509 SubjectPublicKeyInfo structure after decryption, replacing the keys for this object.

(Inherited from ECDiffieHellman)
MemberwiseClone()

Creates a shallow copy of the current Object.

(Inherited from Object)
ToString()

Returns a string that represents the current object.

(Inherited from Object)
ToXmlString(Boolean)

This method is not implemented.

ToXmlString(Boolean)

This method throws in all cases.

(Inherited from ECDiffieHellman)
ToXmlString(ECKeyXmlFormat)
Obsolete.

Serializes the key information to an XML string by using the specified format.

TryExportECPrivateKey(Span<Byte>, Int32)

Attempts to export the current key in the ECPrivateKey format into a provided buffer.

(Inherited from ECDiffieHellman)
TryExportECPrivateKeyPem(Span<Char>, Int32)

Attempts to export the current key in the PEM-encoded ECPrivateKey format into a provided buffer.

(Inherited from ECAlgorithm)
TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan<Byte>, PbeParameters, Span<Byte>, Int32)

Attempts to export the current key in the PKCS#8 EncryptedPrivateKeyInfo format into a provided buffer, using a byte-based password.

TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan<Byte>, PbeParameters, Span<Byte>, Int32)

Attempts to export the current key in the PKCS#8 EncryptedPrivateKeyInfo format into a provided buffer, using a byte-based password.

(Inherited from ECDiffieHellman)
TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan<Char>, PbeParameters, Span<Byte>, Int32)

Attempts to export the current key in the PKCS#8 EncryptedPrivateKeyInfo format into a provided buffer, using a char-based password.

TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan<Char>, PbeParameters, Span<Byte>, Int32)

Attempts to export the current key in the PKCS#8 EncryptedPrivateKeyInfo format into a provided buffer, using a char-based password.

(Inherited from ECDiffieHellman)
TryExportEncryptedPkcs8PrivateKeyPem(ReadOnlySpan<Byte>, PbeParameters, Span<Char>, Int32)

Attempts to export the current key in the PKCS#8 EncryptedPrivateKeyInfo format with a byte-based password, PEM encoded.

(Inherited from AsymmetricAlgorithm)
TryExportEncryptedPkcs8PrivateKeyPem(ReadOnlySpan<Char>, PbeParameters, Span<Char>, Int32)

Exports the current key in the PKCS#8 EncryptedPrivateKeyInfo format with a char-based password, PEM encoded.

(Inherited from AsymmetricAlgorithm)
TryExportPkcs8PrivateKey(Span<Byte>, Int32)

Attempts to export the current key in the PKCS#8 PrivateKeyInfo format into a provided buffer.

TryExportPkcs8PrivateKey(Span<Byte>, Int32)

Attempts to export the current key in the PKCS#8 PrivateKeyInfo format into a provided buffer.

(Inherited from ECDiffieHellman)
TryExportPkcs8PrivateKeyPem(Span<Char>, Int32)

Attempts to export the current key in the PEM-encoded PKCS#8 PrivateKeyInfo format into a provided buffer.

(Inherited from AsymmetricAlgorithm)
TryExportSubjectPublicKeyInfo(Span<Byte>, Int32)

Attempts to export the current key in the X.509 SubjectPublicKeyInfo format into a provided buffer.

(Inherited from ECDiffieHellman)
TryExportSubjectPublicKeyInfoPem(Span<Char>, Int32)

Attempts to export the current key in the PEM-encoded X.509 SubjectPublicKeyInfo format into a provided buffer.

(Inherited from AsymmetricAlgorithm)

Explicit Interface Implementations

IDisposable.Dispose()

This API supports the product infrastructure and is not intended to be used directly from your code.

For a description of this member, see Dispose().

(Inherited from AsymmetricAlgorithm)

Applies to