Generating Diffie-Hellman Keys

The steps necessary for this are shown in the following procedure.

    To generate a Diffie-Hellman public key
  1. Get a handle to the Diffie-Hellman provider.
  2. Generate the new key. There are two ways to accomplish this — by having CryptoAPI generate all new values for G, P, and X or by using existing values for G and P, and generating a new value for X.

    To generate the key by generating all new values:

    Call CryptGenKey passing either CALG_DH_SF (store and forward) or CALG_DH_EPHEM (ephemeral) in the Algid parameter. The key will be generated, using new, random values for G and P, a newly calculated value for X, and its handle will be returned in the phKey parameter.

    The new key is now ready for use. Note that the values of G and P must be sent along with the key (or sent by some other method), when doing a key exchange.

    To generate the key by using predefined values for G and P:

    1. Initialize a CRYPT_DATA_BLOB structure with the pbData member set to the G value. It should contain no header information and should be little-endian format.
    2. Initialize a CRYPT_DATA_BLOB structure with the pbData member set to the P value. It should contain no header information and should be little-endian format.
    3. Call CryptGenKey passing either CALG_DH_SF (store and forward) or CALG_DH_EPHEM (ephemeral) in the Algid parameter, and CRYPT_PREGEN for the dwFlags parameter. A key handle will be generated and returned in the phKey parameter.
    4. The value of G may be set by calling CryptSetKeyParam, passing the key handle (retrieved in step c) in the hKey parameter, the KP_G flag in the dwParam parameter, and a pointer to the structure containing the value of G in the pbData parameter.
    5. The value of P may be set by calling CryptSetKeyParam, passing the key handle (retrieved in step c) in the hKey parameter, the KP_P flag in the dwParam parameter, and a pointer to the structure containing the value of P in the pbData parameter.
    6. The value of X must be generated by calling CryptSetKeyParam, passing the key handle (retrieved in step c) in the hKey parameter, the KP_X flag in the dwParam parameter, and NULL in the pbData parameter.

      If all the function calls succeeded, the D-H public key is ready for use.

  3. When finished with the key, call CryptDestroyKey to destroy the handle (HCRYPTKEY) to the key.

If CALG_DH_SF was specified in the previous procedures, the key values are persisted to storage with each call to CryptSetKeyParam. The G and P values can then be retrieved using CryptGetKeyParam. Some CSPs may have hard-coded G and P values. In this case a NTE_FIXEDPARAMETERS error will be returned if CryptSetKeyParam is called with KP_G or KP_P specified in the dwParam parameter. If CryptDestroyKey is called, the handle to the key is destroyed, but the key values are retained in the CSP. However, if CALG_DH_EPHEM was specified, the handle to the key is destroyed and all values are purged from the CSP.