Почему мой зашифрованный текст не меняется?

У меня работает эта программа, которая шифрует строку из 9 байтов, используя AES128 из wincrypt.h но что-то странное происходит, когда я меняю последний символ клавиши:

от L"3igcZhRdWq96m3GUmTAiv2" например L"3igcZhRdWq96m3GUmTAiv1" или же L"3igcZhRdWq96m3GUmTAiv9" зашифрованные тексты все равно совпадают.

#include <Windows.h>
#include <wincrypt.h>
#include <stdio.h>
#pragma comment(lib, "crypt32.lib")

#define BUFFER_SIZE 16

//params: <input file> <output file> <is decrypt mode> <key>
int wmain()
{

    wchar_t key[] = L"3igcZhRdWq96m3GUmTAiv2";
    wchar_t *key_str = key;


    size_t len = lstrlenW(key_str);


    DWORD dwStatus = 0;
    BOOL bResult = FALSE;
    wchar_t info[] = L"Microsoft Enhanced RSA and AES Cryptographic Provider";
    HCRYPTPROV hProv;

    if (!CryptAcquireContextW(&hProv, NULL, info, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
        dwStatus = GetLastError();
        printf("CryptAcquireContext failed: %x\n", dwStatus);
        CryptReleaseContext(hProv, 0);
        system("pause");
        return dwStatus;
    }
    HCRYPTHASH hHash;
    if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
        dwStatus = GetLastError();
        printf("CryptCreateHash failed: %x\n", dwStatus);
        CryptReleaseContext(hProv, 0);
        system("pause");
        return dwStatus;
    }

    if (!CryptHashData(hHash, (BYTE*)key_str, len, 0)) {
        DWORD err = GetLastError();
        printf("CryptHashData Failed : %#x\n", err);
        system("pause");
        return (-1);
    }
    printf("[+] CryptHashData Success\n");

    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 = BUFFER_SIZE;
    BYTE string[string_size] = { "Fooooooo" };
    DWORD out_len = 9;



    if (!CryptEncrypt(hKey, NULL, TRUE, 0, string, &out_len, string_size)) {
            printf("[-] CryptEncrypt failed\n");
    }


    for (DWORD i = 0; i < out_len; i++)
        printf("%02x ", string[i]);
    printf("\n"); 

    printf("%lu\n", out_len);
    //printf("%s", string);
    //printf("\n");

    if (!CryptDecrypt(hKey, NULL, TRUE, 0, string, &out_len)) {
        printf("[-] CryptDecrypt failed\n");
    }

    printf("%lu\n", out_len);
    printf("%s", string);
    printf("\n");

    memset(string, 0, string_size);

    CryptReleaseContext(hProv, 0);
    CryptDestroyKey(hKey);
    CryptDestroyHash(hHash);

    printf("Finished\n");
    system("pause");
    return 0;

}

Также обратите внимание, что хэши SHA256 клавиш, которые я выставлял ранее, отличаются друг от друга:

3igcZhRdWq96m3GUmTAiv2 -> F5584805AA52AC68062331F3B852001F2585D23105C22D61CF25C3C71D998F9B
3igcZhRdWq96m3GUmTAiv1 -> 25DF6A58974E67ABD2DE6EE29F1A045F87ADCDC05C879235C450D12ABAA549C1
3igcZhRdWq96m3GUmTAiv9 -> AE6FFA99AFF1A72ED31B4A16CE86CE060B1DB3C0ECA3769F27D8891155B1E16D

Источник: https://passwordsgenerator.net/sha256-hash-generator/

Если я изменю средний или первый символ ключа (например, первые 3) или добавлю больше символов, зашифрованный текст на этот раз изменится в соответствии с ожидаемым поведением.

Вы знаете, почему так происходит? Зашифрованный текст должен измениться, если я изменю какой-либо символ ключа, но этого не происходит, когда я изменяю только последний символ.

1 ответ

Решение
if (!CryptHashData(hHash, (BYTE*)key_str, len, 0)) {

Вы проходите lenдлина key_str в символах (wchar_t), в то время как CryptHashData ожидает количество байтов. Это означает, что он эффективно использует только первую половину key_str (как wchar_t это 2 байта на Win32).

Вы можете это легко исправить:

if (!CryptHashData(hHash, (BYTE*)key_str, len*sizeof(*key_str), 0)) {
Другие вопросы по тегам