Я пытаюсь использовать 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 без успеха (поэтому я считаю, что это невозможно).
Вы можете применить режим цепочки 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;
}
Других решений пока нет …