Не шифруйте правильно wincrypt
Я пытаюсь зашифровать строку размером 8 байт (64 бита) с помощью AES128 из wincrypt.h
Обратите внимание, что строка меньше, чем размер блока AES, который составляет 128 бит.
HCRYPTKEY hKey;
if (!CryptDeriveKey(hProv, CALG_AES_128, hHash, 0, &hKey)) {
dwStatus = GetLastError();
printf("CryptDeriveKey failed: %x\n", dwStatus);
CryptReleaseContext(hProv, 0);
system("pause");
return dwStatus;
}
printf("[+] CryptDeriveKey Success\n");
const size_t string_size = 8;
BYTE string[8] = { "Foooooo" }; // \0 counts as 1 byte
DWORD out_len = 8;
if (!CryptEncrypt(hKey, NULL, TRUE, 0, string, &out_len, string_size)) {
printf("[-] CryptEncrypt failed\n");
}
printf("%s", string);
printf("\n");
if (!CryptDecrypt(hKey, NULL, TRUE, 0, string, &out_len)) {
printf("[-] CryptDecrypt failed\n");
}
printf("%s", string);
printf("\n");
Но он не выглядит хорошо для шифрования / дешифрования, потому что я получаю этот вывод:
[+] CryptDeriveKey Success
Fooooooo
[-] CryptEncrypt failed
ÉÆ╠1╔P█ídhù;$§┴
[-] CryptDecrypt failed
Что я делаю не так? &out_len
или же string_size
должно быть 128 как размер блока AES?
1 ответ
Документы для CryptEncrypt указывают, что длина ввода / вывода указана в байтах, поэтому для AES* это число должно быть кратно 16
Я думаю, это также является ключом к вашей проблеме: CryptEncrypt работает на месте, то есть перезаписывает входной открытый текст выходным зашифрованным текстом. Ваш буфер слишком мал для получения 16-байтового вывода, поэтому последние 8 байт, скорее всего, повреждены между операциями шифрования и дешифрования.
Попробуйте натолкнуться
BYTE string[8] = { "Foooooo" };
const size_t string_size = 8;
в
BYTE string[16] = { "Foooooo" };
const size_t string_size = 16;
Также ознакомьтесь с заполнением PKCS7, которое, вероятно, определяет, как wincrypt определяет, что ваш зашифрованный текст плох.
* за исключением режимов кражи зашифрованного текста или потоковых режимов. Эти режимы не могут "потерпеть неудачу" при дешифровании, поэтому wincrypt не использует ни один из них.
Не относится к вашему вопросу, но печатает зашифрованный текст через printf
тоже не очень хорошая идея. Вы получите лучшее понимание, напечатав зашифрованный текст в шестнадцатеричном виде:
{DWORD i;
for(DWORD i=0; i < out_len; i++)
printf("%02x ", string[i]);
printf("\n");}