When encrypting or decrypting data simultaneously with the same key, the same physical session key must not be used for both operations. This is because every session key contains internal state data that becomes jumbled if it is used for more than one operation at a time. A simple solution to this problem is to make a copy of the session key so that the original key can be used for one operation and the copy used for the other.
Copying a session key is done by exporting the key with CryptExportKey and then using CryptImportKey to import it back in. When the key is imported, the CSP gives the imported key its own section of internal memory, as if it were not related to the original key.
The following code example shows how a copy of a session key can be obtained.
HCRYPTPROV hProv; // Handle to a CSP
HCRYPTKEY hKey; // Handle to a session key
HCRYPTKEY hCopyKey = 0,
hPubKey = 0;
BYTE pbBlob[256];
DWORD dwBlobLen;
// Get a handle to your own key exchange public key.
CryptGetUserKey (hProv, AT_KEYEXCHANGE, &hPubKey);
// Export the session key into a key BLOB.
dwBlobLen = 256;
CryptExportKey (hKey, hPubKey, SIMPLEBLOB, 0, pbBlob, &dwBlobLen);
// Import the session key back into the CSP. This is stored separately
// from the original session key.
CryptImportKey (hProv, pbBlob, dwBlobLen, 0, 0, &hCopyKey);
This technique should not be used with stream ciphers because stream cipher keys should never be used more than once. Instead, use separate keys to transmit and receive data.