c++ - OpenSSL和JSON文件加解密

标签 c++ encryption openssl

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

我将文件内容读入字符串(字符数组),在解密 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;
}

最佳答案

这是一个明显的错误:

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

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

string encryptedStr = encryptedStreamStr.str();

A 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 ,明确表示这不是文本字符串。它是二进制数据。

关于c++ - OpenSSL和JSON文件加解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42260141/

相关文章:

c++ - 在 For 循环 C++ 中创建线程

c++ - 编译c/cpp文件时scons "Depends"什么时候有用?

encryption - 如何在 C# 中从内存中删除加密 key ?

c++ - shared boost::shared_ptr<> 变量是线程安全的吗?

c++ - 我什么时候应该使用 std::string/std::string_view 作为参数/返回类型

java - 在 Spring 配置文件中加密密码

android - 拖放应用程序构建器许可。如何确保源代码不会被反编译和重复使用?

c - 在 AES 密码对象上禁用 PKCS#7 填充?

linux - 为什么 openssl/md5.h 链接到 "crypto"而不是 "ssl"

openssl - 无法连接到 Indy SSL TCP 服务器