зашифровать сообщение crypto api

Использую microsoft crypto api для зашифрования сообщения. Вот код:

char str[16] = "mamamama";
DWORD count = strlen(str);

HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
HCRYPTHASH hHash = 0;

CHAR szPassword[] = "123456\0";
DWORD dwLength;
dwLength = (DWORD)strlen(szPassword);

FILE* fp;
char name[] = "C:\\pg\\log.txt";
fp = fopen(name, "w");

if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET))//PROV_RSA_FULL
{
    fprintf(fp, "%u,%s", GetLastError(), "CryptAcquireContext DEL\n");
}

if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))//PROV_GOST_2012_256
{
    fprintf(fp, "%u,%s", GetLastError(), "CryptAcquireContext\n");
    fclose(fp);
    return 69;
}

if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
{
    fprintf(fp, "%u,%s", GetLastError(), "CryptCreateHash\n");
    fclose(fp);
    return 69;
}

// Хэширование строки пароля.
if (!CryptHashData(hHash, (BYTE*)szPassword, dwLength, 0))
{
    fprintf(fp, "%u,%s", GetLastError(), "CryptHashData\n");
    fclose(fp);
    return 69;
}

// Создание сессионного ключа, основанного на хэше, полученного из пароля.
if (!CryptDeriveKey(hProv, CALG_RC2, hHash, CRYPT_EXPORTABLE, &hKey))
{
    fprintf(fp, "%u,%s", GetLastError(), "CryptDeriveKey\n");
    fclose(fp);
    return 69;
}

int str_len = strlen(str);
DWORD buf_len = 0;

//узнаю нужную длину буфера
if(!CryptEncrypt(hKey, 0, true, 0, 0, &buf_len, str_len))
{
    fprintf(fp, "%u,%s", GetLastError(), "CryptEncrypt size");
    fclose(fp);
}


BYTE* data = new BYTE[buf_len];
int i = 0;
while (str[i] != '\0')
{
    data[i] = (BYTE)str[i];
    ++i;
}
//зашифрование
if(!CryptEncrypt(hKey, 0, true, 0, data, &buf_len, str_len))
{
    fprintf(fp, "%u,%s", GetLastError(), "CryptEncrypt");
    fclose(fp);
}

Последний GetLastError выдает ошибку 234 - More data is available. Что не так?


Ответы (1 шт):

Автор решения: user7860670

Мне кажется, вы перепутали последние два параметра. Последний должен содержать полный размер буфера. А предпоследний должен указывать на переменную, изначально содержащую размер входных данных, а затем получающую размер записанных данных.

DWORD const str_len = (DWORD) strlen(str);
DWORD len = str_len;
DWORD buf_len = 0;
BYTE * data = NULL;

//узнаю нужную длину буфера
if(!CryptEncrypt(hKey, NULL, TRUE, 0, data, &len, buf_len))
{
    fprintf(fp, "%u,%s", GetLastError(), "CryptEncrypt size");
    fclose(fp);
}

buf_len = len;
len = str_len;
data = (BYTE *) malloc(buf_len);
memcpy(data, str, str_len);

//зашифрование
if(!CryptEncrypt(hKey, NULL, TRUE, 0, data, &len, buf_len))
{
    fprintf(fp, "%u,%s", GetLastError(), "CryptEncrypt");
    fclose(fp);
}
→ Ссылка