3

I'm trying to use the NCrypt.dll to encrypt some data, in C++, and I'm having trouble handling keys and algorithms.

I would like to use AES with the CBC chainging method but, can't get the NCryptEncrypt function to work (I keep getting an invalid buffer size thrown).

I have created and stored a key (in the key storage provider) using the NCRYPT_AES_ALGORITHM flag but, have no idea how to set the algorithm to use the CBC method.

    secSt = NCryptCreatePersistedKey(phProvider, &keyHndl, NCRYPT_AES_ALGORITHM, keyname, 0, 0);

I've tried a few property settings and had no success so, I would like to know if this is even possible with NCrypt?

I know the Bcrypt encrypt function allows this and tried to convert my NCRYPT_KEY_HANDLE to a BCRYPT_KEY_HANDLE without success (so I reckon this is not possible).

4

1 回答 1

2

您可以通过使用NCryptSetProperty和 BCrypt 常量来应用链接模式 CBC BCRYPT_CHAIN_MODE_CBC

请注意,NCryptEncrypt它似乎不支持对称密钥的填充(请参阅NCryptEncryptdwFlags中的参数描述)。所以我不得不应用一些穷人的明文填充来获得 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;
}
于 2017-01-07T19:36:21.903 回答