# Diffie-Hellman Version 3 Private Key BLOBs

When a Diffie-Hellman version 3 *private key* BLOB is exported, it is in a format as follows:

```
BLOBHEADER blobheader;
DHPRIVKEY_VER3 dhprivkeyver3;
BYTE p[dhprivkeyver3.bitlenP/8];
// Where P is the prime modulus
BYTE q[dhprivkeyver3.bitlenQ/8];
// Where Q is a large factor of P-1
BYTE g[dhprivkeyver3.bitlenP/8];
// Where G is the generator parameter
BYTE j[dhprivkeyver3.bitlenJ/8];
// Where J is (P-1)/Q
BYTE y[dhprivkeyver3.bitlenP/8];
// Where Y is (G^X) mod P
BYTE x[dhprivkeyver3.bitlenX/8];
// Where X is the private exponent
```

This *BLOB* format is exported when the CRYPT_BLOB_VER3 flag is used with **CryptExportKey**. Because the version is in the BLOB, there is no need to specify a flag when using this BLOB with **CryptImportKey**.

The following table describes each component of the *key BLOB*.

Field | Description |
---|---|

blobheader | A BLOBHEADER structure. |

dhprivkeyver3 | A DHPRIVKEY_VER3 structure. The magic member should be set to 0x34484400 for private keys. Notice that the hexadecimal value is just an ASCII encoding of "DH4". |

P | The P value is located directly after the DHPRIVKEY_VER3 structure, and should always be the length in bytes of the DHPRIVKEY_VER3 bitlenP field (bit length of P) divided by eight (little-endian format). |

Q | The Q value is located directly after the P value and should always be the length in bytes of the DHPRIVKEY_VER3 bitlenQ field divided by eight (little-endian format). If the bitlenQ value is 0, then the value is absent from the BLOB. |

G | The G value is located directly after the Q value and should always be the length in bytes of the DHPRIVKEY_VER3 bitlenP field (bit length of P) divided by eight. If the length of the data is one or more bytes shorter than P divided by 8, the data must be padded with the necessary bytes (of zero value) to make the data the desired length (little-endian format). |

J | The J value is located directly after the G value and should always be the length in bytes of the DHPRIVKEY_VER3 bitlenJ field divided by eight (little-endian format). If the bitlenJ value is 0, then the value is absent from the BLOB. |

Y | The Y value, (G^X) mod P, is located directly after the J value, and should always be the length in bytes of the DHPRIVKEY_VER3 bitlenP field (bit length of P) divided by eight. If the length of the data that results from the calculation of (G^X) mod P is one or more bytes shorter than P divided by 8, the data must be padded with the necessary bytes (of zero value) to make the data the desired length (little-endian format). |

X | The X value is a random large integer such that the public portion of the DH key pair, Y, is equal to: Y = (G^X) mod P |

When calling **CryptExportKey**, the developer can choose whether to encrypt the key. The key is encrypted if the *hExpKey* parameter contains a valid handle to a session key. Everything but the **BLOBHEADER** portion of the BLOB is encrypted. Note that the encryption algorithm and encryption key parameters are not stored along with the *private key BLOB*. The application must manage and store this information. If zero is passed for *hExpKey*, the private key will be exported without encryption.

Note

It is dangerous to export private keys without encryption because they are then vulnerable to interception and use by unauthorized entities.