我已成功使用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;
}
答案 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
会更加困惑,因此明确表示这不是文本字符串。这是二进制数据。