您可以使用NCryptSetProperty 和BCrypt 常量BCRYPT_CHAIN_MODE_CBC 应用链接模式CBC。
请注意NCryptEncrypt 似乎不支持对称密钥的填充(参见NCryptEncrypt 中参数dwFlags 的描述)。所以我不得不应用一些穷人的明文填充来获得 16 个字节的倍数。如果没有填充,我也会得到状态码 0xc0000206 (STATUS_INVALID_BUFFER_SIZE)。
// Clear text for testing
static const char* clearText = "The quick brown fox jumps over the lazy dog. 1234567890. ";
static const int clearTextLen = 64;
int main()
{
LPCWSTR keyName = L"NCryptTest";
SECURITY_STATUS status;
NCRYPT_PROV_HANDLE hProvider;
NCRYPT_KEY_HANDLE hKey;
// Open storage provider
status = NCryptOpenStorageProvider(&hProvider, NULL, 0);
// Get stored key
status = NCryptOpenKey(hProvider, &hKey, keyName, 0, 0);
if (status == NTE_BAD_KEYSET)
{
// Create key if it doesn't exist
status = NCryptCreatePersistedKey(hProvider, &hKey, BCRYPT_AES_ALGORITHM, keyName, 0, 0);
status = NCryptFinalizeKey(hKey, 0);
}
// Set the chaining mode CBC
LPCWSTR chainMode = BCRYPT_CHAIN_MODE_CBC;
status = NCryptSetProperty(hKey, NCRYPT_CHAINING_MODE_PROPERTY, (PBYTE)chainMode, wcslen(chainMode) * 2 + 2, 0);
// Encrypt the text
DWORD outlen = -1;
unsigned char* cipherData = new unsigned char[clearTextLen];
status = NCryptEncrypt(hKey, (PBYTE)clearText, clearTextLen, NULL, cipherData, clearTextLen, &outlen, 0);
// Cleanup
delete[] cipherData;
NCryptFreeObject(hKey);
NCryptFreeObject(hProvider);
return 0;
}