Всем привет!
Пытаю WinAPI`шную технологию шифрования данных через CNG с симметричным алгоритмом AES-GCM. Прочёл кучу теории. Просмотрел чуть меньше исходников под реализацию именно AES-GCM. Решил реализовать в таком виде исходный код
Код отваливается на строке:
с ошибкой функции BCryptSetProperty 0xC000000D. Вроде этот код дешифруется так: STATUS_INVALID_PARAMETER.
Через пошаговую загрузку посмотрел какие значение всех параметров вводятся в функцию. Всё норм.
Вывел эти же значения через cout на экран. Так же всё на месте.
Решил поэкспериметировать со значениями iv. Увеличил до 16 байт. Тогда отвал переместился на строку
с тем же кодом ошибки.
Чтение документации с сайта мелкомягких даёт мало инфы. Вообще странно, что ошибка не указывает какой именно из параметров косячный.
Гугление особо не даёт инфы как эту проблему решать. Находил инфу по другим ЯП. Там помогало явное задание dwFlags=0. У меня он принимает это значение в качестве аргумента обоих функций.
Не знаю ещё в какую сторону капнут. Поэтому прошу помощи. Кто то знает как завести эту мелкомягкую балалайку?
Пытаю WinAPI`шную технологию шифрования данных через CNG с симметричным алгоритмом AES-GCM. Прочёл кучу теории. Просмотрел чуть меньше исходников под реализацию именно AES-GCM. Решил реализовать в таком виде исходный код
C++:
#include <windows.h>
#include <bcrypt.h>
#include <iostream>
#include <vector>
#include <string>
#pragma comment(lib, "bcrypt.lib")
void handleError(NTSTATUS status, const wchar_t* s) {
if (status != STATUS_SUCCESS) {
std::cerr << "Error: " << std::hex << status << std::endl;
std::wcout << s << std::endl;
exit(1);
}
}
std::vector<BYTE> encrypt(const std::string& plaintext, const std::vector<BYTE>& key, const std::vector<BYTE>& iv) {
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_KEY_HANDLE hKey;
DWORD cbData;
NTSTATUS status;
// Создаем алгоритм AES
handleError(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, NULL, 0), L"Create AES");
// Создаем ключ
handleError(BCryptGenerateSymmetricKey(hAlg, &hKey, NULL, 0, (PUCHAR)key.data(), key.size(), 0), L"Create key");
// Устанавливаем параметры для GCM
handleError(BCryptSetProperty(hKey, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), 0), L"Create GCM");
handleError(BCryptSetProperty(hKey, BCRYPT_INITIALIZATION_VECTOR, (PUCHAR)iv.data(), iv.size(), 0), L"Create IV");
// Выделяем память для шифрованного текста
std::vector<BYTE> ciphertext(plaintext.size());
DWORD cbCiphertext = 0;
// Шифруем данные
handleError(BCryptEncrypt(hKey, (PUCHAR)plaintext.data(), plaintext.size(), NULL, (PUCHAR)iv.data(), iv.size(),
ciphertext.data(), ciphertext.size(), &cbCiphertext, 0), L"Crypt");
// Очищаем ресурсы
BCryptDestroyKey(hKey);
BCryptCloseAlgorithmProvider(hAlg, 0);
ciphertext.resize(cbCiphertext);
return ciphertext;
}
int main() {
// Пример данных
std::string plaintext = "Hello, World!";
// Ключ 16 байт для AES-128
std::vector<BYTE> key = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
//IV 12 байт (4 байта будет заполняться счётчиком
std::vector<BYTE> iv = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b
};
// Шифруем
std::vector<BYTE> ciphertext = encrypt(plaintext, key, iv);
// Выводим шифрованные данные в шестнадцатичном формате
for (BYTE byte : ciphertext) {
std::cout << std::hex << (int)byte;
}
std::cout << std::endl;
return 0;
}
Код отваливается на строке:
C++:
handleError(BCryptSetProperty(hKey, BCRYPT_INITIALIZATION_VECTOR, (PUCHAR)iv.data(), iv.size(), 0), L"Create IV");
Через пошаговую загрузку посмотрел какие значение всех параметров вводятся в функцию. Всё норм.
Вывел эти же значения через cout на экран. Так же всё на месте.
Решил поэкспериметировать со значениями iv. Увеличил до 16 байт. Тогда отвал переместился на строку
C++:
handleError(BCryptEncrypt(hKey, (PUCHAR)plaintext.data(), plaintext.size(), NULL, (PUCHAR)iv.data(), iv.size(),ciphertext.data(), ciphertext.size(), &cbCiphertext, 0), L"Crypt");
Чтение документации с сайта мелкомягких даёт мало инфы. Вообще странно, что ошибка не указывает какой именно из параметров косячный.
Гугление особо не даёт инфы как эту проблему решать. Находил инфу по другим ЯП. Там помогало явное задание dwFlags=0. У меня он принимает это значение в качестве аргумента обоих функций.
Не знаю ещё в какую сторону капнут. Поэтому прошу помощи. Кто то знает как завести эту мелкомягкую балалайку?