An OPAQUEKEYBLOB exported via CryptExportKey on Windows 7 is incompatible with Windows 8.1

I recently ran into a customer having decryption problems on Windows 8.1. 
The data was encrypted using a symmetric key created on Windows 7 and exported as an OPAQUEKEYBLOB.
When importing the key on Windows 8.1 and then attempting to decrypt, CryptDecrypt failed with NTE_BAD_DATA.
It turns out that there was a fair amount of code change to CryptoAPI on Windows 8.1 and the OPAQUEKEYBLOB is slightly different from Windows 7.

The key blob is compatible moving in the following directions:
Win 7 -> Win 7
Win 8.1 -> Win 8.1
Win 8.1 -> Win 7

However, when going from Win 7 -> Win 8.1, there's a different interpretation of the key blob.
There's an easy fix to this problem. There is an offset (0x14) that indicates the size of what is defined as a "packed key".
If this size is set 0, the Win 8.1 code will execute a different code path and successfully imports the key blob.

// lpBlob contains the OPAQUEKEYBLOB
*(DWORD *)(lpBlob + 0x14) = 0; // Set the packed key length to zero

bResult = CryptImportKey(hProv, lpBlob, dwBlobLength, 0, CRYPT_EXPORTABLE, &hKey);

if (bResult == FALSE)
// Import failed

// Decrypt the data
bResult = CryptDecrypt(hKey, 0, TRUE, 0, lpCypherText, &dwCypherTextLength);

if (bResult == FALSE)
// Decryption failed

// Decryption succeeded

Comments (1)

Skip to main content