CryptDecrypt仅解密第一个字节

时间:2016-10-06 19:33:44

标签: c++ winapi cryptography cryptoapi

我正在使用Windows Crypto API并且无法解密文件。在CryptDecrypt之后,我的文件的第一个字节被解密,但其他字节都是垃圾。

例如:

01234567012345670123456701234567012345670123456701234567012345670123456701234
56701234567012345670123456701234567012345670123456701234567012345670123456701
23456701234567012345670123456701234567012345670123456701234567012345670123456
70123456701еzc^HЏ-v"ЙЂQЋ;Ђ©ЕЮЃЛќА ы§Чюн-D„=оШХU†>™B‰Кy)Л¬6A)жO0”~sjё;<Лxj:("Ц
TвeхфOУKCв]H°фі"XШ8S{±~Ф\+a]gmъШie,Zџ§0ыќQq1ђ$sѓI~Чроы_2f

这是MCVE。我从文件input.txt读取内容,ecnrypt它,写入文件encrypted.txt。然后我阅读encrypted.txt并使用相同的密钥对其进行解密并保存到decrypted.txt。 decrypted.txt的唯一第一个字节是正确的。

#include "stdafx.h"
#include <fstream>
#include <Windows.h>
#include <wincrypt.h>

using namespace std;

HCRYPTPROV hProvider;
HCRYPTKEY hKey;


char* readFile(const char* filename, DWORD* bufferSize);
void encrypt();
void decrypt();

int main()
{
    //Create  context
    if (!CryptAcquireContextA(&hProvider, "container", NULL, PROV_RSA_FULL, 0))
    {
        if (!CryptAcquireContextA(&hProvider, "container", NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
            return 1;
    }

    //Create key
    CryptGenKey(
        hProvider,
        CALG_RC4,
        CRYPT_EXPORTABLE,
        &hKey);

    encrypt();
    decrypt();
}

//Read all file content
char* readFile(const char* filename, DWORD* bufferSize)
{
    //Чтение исходного файла
    ifstream is(filename);

    is.seekg(0, std::ios::end);
    *bufferSize = is.tellg();
    is.seekg(0, std::ios::beg);

    char* buffer = new char[*bufferSize];
    is.read(buffer, *bufferSize);
    is.close();

    return buffer;
}

void encrypt()
{
    //Read file
    DWORD dataSize;
    char* data = readFile("input.txt", &dataSize);

    //Encrypt
    CryptEncrypt(
        hKey,
        NULL,
        true,
        NULL,
        (unsigned char*)data,
        &dataSize,
        dataSize
    );

    //Write file
    ofstream os("encrypted.txt");
    os.write(data, dataSize);
    os.close();

    delete[] data;
 }

void decrypt()
{
    //Read file
    DWORD dataSize;
    char* data = readFile("encrypted.txt", &dataSize);

    //Encrypt
    CryptDecrypt(
        hKey,
        NULL,
        true,
        NULL,
        (unsigned char*)data,
        &dataSize
    );

    //Write file
    ofstream os("decrypted.txt");
    os.write(data, dataSize);
    os.close();

   delete[] data;
}

1 个答案:

答案 0 :(得分:0)

我猜你做的和我一样 - 将数据添加到加密文件然后尝试解密...好吧,似乎你无法使用未加密的CryptDecrypt解密数据马上。

如果要将数据添加到现有加密文件中,您需要首先将其内容读取到内存并对其进行解密(oldData),然后添加newData,将所有加密文件加在一起oldData + newData然后写入文件(覆盖)。 它适用于我的代码:

{{1}}