Не шифруйте правильно 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");}

Другие вопросы по тегам