我已成功使用 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/