Используйте AES CBC с NCrypt в Windows

Я пытаюсь использовать NCrypt.dll для шифрования некоторых данных в C ++, и у меня возникают проблемы с обработкой ключей и алгоритмов.

Я хотел бы использовать AES с методом CBC Chainging, но не могу получить NCryptEncrypt функция для работы (я получаю неверный размер буфера).

Я создал и сохранил ключ (в поставщике хранилища ключей), используя NCRYPT_AES_ALGORITHM флаг, но не знаю, как настроить алгоритм для использования метода CBC.

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

Я пробовал несколько настроек свойств, но безуспешно, поэтому я хотел бы знать, возможно ли это с NCrypt?

Я знаю, что функция шифрования Bcrypt позволяет это и пытался конвертировать мой NCRYPT_KEY_HANDLE к BCRYPT_KEY_HANDLE без успеха (поэтому я считаю, что это невозможно).

3

Решение

Вы можете применить режим цепочки CBC с помощью NCryptSetProperty и константа BCrypt BCRYPT_CHAIN_MODE_CBC,

Обратите внимание, что NCryptEncrypt похоже, не поддерживает заполнение для симметричных клавиш (см. описание параметра dwFlags в NCryptEncrypt). Таким образом, я должен был применить заполнение открытого текста каким-то бедняком, чтобы получить кратное 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;
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]