Reputation: 1407
I've successfully used the openssl library to encrypt a file (jsonOut.crypto). However, I can't successfully read that encrypted file into a char array and decrypt with the below c++ code.
I read the file contents into a string (char array), iterate over that array while decrypting a buffer of 16 bytes, inserting those 16 bits in an array, and inserting that array into a file object.
However, the decrypted file looks like gibberish. It's different than the encrypted file, but still looks encrypted none the less. Can someone look through my code for obvious errors?
Please do not suggest another library. This isn't production code to get the highest level of crypto possible - it's just quickly put something together.
Thanks!
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;
}
Upvotes: 1
Views: 3222
Reputation: 118425
Here's one obvious error:
stringstream encryptedStreamStr;
encryptedStreamStr << inEncryptedFile.rdbuf();
This is presumed to be your encrypted file. This is binary data.
string encryptedStr = encryptedStreamStr.str();
A std::string
is meant to be used with text strings. Not binary data. Although a std::string
shouldn't have issues with swallowing binary data that was read in the above manner, the following is going to be a problem:
int lenDecrypt = strlen(encryptedStr.c_str());
strlen()
is a C library function that knows absolutely nothing about C++ strings. It determines the length of the string by looking for the first '\0' byte. Which is unlikely to give you the true size of the encrypted binary blob, sine the binary blob would certainly have \0
bytes. So, at the very least, the computed size of the encrypted file is going to be wrong here.
The shown code is also using strlen
when reading the original file to encrypt. It's unclear whether the original file is plain text or binary. If the file getting encrypted is binary, the same bug occurs when reading the original file.
Next problem:
for (int k = 0; k <= 16; k++) {
outFile << encryptedbuffer[k];
}
This is going to write 17 bytes to the output file, and not 16, as your obvious intent is.
The same bug occurs when encrypting the file. The original file getting encrypted is getting corrupted right off the bat. Game over.
In conclusion: a std::string
is meant to be used, well, with text strings. Although std::string
can be used correctly, and safely, with binary data, this'll often lead to confusion.
It's going to be less confusing to use std::vector<char>
with binary data, rather than std::string
, making it explicit that this is not a text string. It's binary data.
Upvotes: 4