OpenSSL和JSON文件加密和解密

时间:2017-02-15 21:11:50

标签: c++ encryption openssl

我已成功使用openssl库加密文件(jsonOut.crypto)。但是,我无法成功将该加密文件读入char数组并使用以下c ++代码进行解密。

我将文件内容读入字符串(char数组),迭代该数组,同时解密16字节的缓冲区,将16位插入数组,然后将该数组插入文件对象。

然而,解密的文件看起来像胡言乱语。它与加密文件不同,但仍然看起来是加密的。有人可以通过我的代码查看明显的错误吗?

请不要建议其他图书馆。这不是生产代码,可以获得最高级别的加密 - 它只是快速将一些东西放在一起。

谢谢!

int main()
{
    // read json file into memory
    ifstream inFile;
    inFile.open("file.json");

    stringstream strStream;
    strStream << inFile.rdbuf();
    string str = strStream.str();

    // create buffer and buffer input/output
    int len = strlen(str.c_str());
    unsigned char encryptedbuffer[128];

    // CODE FOR ENCRYPTION
    unsigned char oneKey[] = "abcdefghijklmnop";
    AES_KEY key;

    // encryption - could make into function?
    AES_set_encrypt_key(oneKey,128,&key);

    ofstream outFile;
    outFile.open("jsonOut.crypto");

    for(int i = 0; i <= len; i += 16) {
        AES_encrypt((const unsigned char *) str.c_str() + i,encryptedbuffer,&key);
        for (int k = 0; k <= 16; k++) {
            outFile << encryptedbuffer[k];
        }
    }

    outFile.close();
    inFile.close();

    // read encrypted file into memory
    ifstream inEncryptedFile;
    inEncryptedFile.open("jsonOut.crypto");

    stringstream encryptedStreamStr;
    encryptedStreamStr << inEncryptedFile.rdbuf();
    string encryptedStr = encryptedStreamStr.str();

    // create buffer and buffer input/output
    int lenDecrypt = strlen(encryptedStr.c_str());
    unsigned char outbufferDecrypt[lenDecrypt];

    AES_set_decrypt_key(oneKey,128,&key);

    ofstream outFileDecrypt;
    outFileDecrypt.open("jsonOut.decrypt");

    for(int j = 0; j <= lenDecrypt; j += 16){
        AES_decrypt((const unsigned char *) encryptedStr.c_str() + j,outbufferDecrypt,&key);
        for (int k = 0; k <= 16; k++) {
            outFileDecrypt << outbufferDecrypt[k];
        }
    }

    outFileDecrypt.close();
    inEncryptedFile.close();

    return 0;
}

1 个答案:

答案 0 :(得分:3)

这是一个明显的错误:

stringstream encryptedStreamStr;
encryptedStreamStr << inEncryptedFile.rdbuf();

这被认为是您的加密文件。这是二进制数据。

string encryptedStr = encryptedStreamStr.str();

std::string旨在与文本字符串一起使用。不是二进制数据。虽然std::string不应该吞下以上述方式读取的二进制数据的问题,但以下是一个问题:

int lenDecrypt = strlen(encryptedStr.c_str());

strlen()是一个C库函数,它对C ++字符串一无所知。它通过查找第一个'\ 0'字节来确定字符串的长度。这不太可能为您提供加密二进制blob的真实大小,正弦二进制blob肯定会有\0个字节。因此,至少,加密文件的计算大小在这里是错误的。

在阅读要加密的原始文件时,显示的代码也使用strlen。目前还不清楚原始文件是纯文本还是二进制文件。如果加密的文件是二进制文件,则在读取原始文件时会出现相同的错误。

下一个问题:

for (int k = 0; k <= 16; k++) {
    outFile << encryptedbuffer[k];
}

这将写入17个字节到输出文件,而不是16个,因为你明显的意图是。

加密文件时会出现同样的错误。加密的原始文件立即被破坏。游戏结束。

总之:std::string意味着使用文本字符串。虽然std::string可以正确,安全地使用二进制数据,但这通常会导致混淆。

std::vector<char>用于二进制数据而不是std::string会更加困惑,因此明确表示这不是文本字符串。这是二进制数据。