Reputation: 855
I am creating an application which encrypts some text and then it writes it to a file. The problem I am seeing is that when I run the encryption more than once, I am only able to decrypt the text I added firstly.
This is the code:
encrypt and decrypt functions:
std::vector<char> CryptCTR::encrypt(const char* textToEncrypt)
{
size_t sizeToEncrypt = strlen(textToEncrypt);
std::vector< char > encryptedText ( sizeToEncrypt );
unsigned long long lengthProcessed = 0;
do {
auto maxCipherLen = sizeToEncrypt > std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : sizeToEncrypt;
encryptCTR(textToEncrypt,
&encryptedText[lengthProcessed],
maxCipherLen);
lengthProcessed += maxCipherLen;
sizeToEncrypt -= maxCipherLen;
} while (sizeToEncrypt > 0);
return encryptedText;
}
std::vector<char> CryptCTR::decrypt(const char* textToDecrypt/*, SecurityKey& key*/)
{
size_t sizeToDecrypt = strlen(textToDecrypt);
unsigned long long lengthProcessed = 0;
std::vector< char > recoveredText ( sizeToDecrypt );
do
{
int maxPlainLen = sizeToDecrypt > std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : sizeToDecrypt;
decryptCTR(textToDecrypt,
&recoveredText[lengthProcessed],
sizeToDecrypt/*, &key*/);
lengthProcessed += maxPlainLen;
sizeToDecrypt -= maxPlainLen;
} while(sizeToDecrypt > 0);
return recoveredText;
}
void CryptCTR::encryptCTR ( const char* pvBufferIn, char* pvBufferOut, unsigned long dwLength )
{
CRYPTO_ctr128_encrypt(
(const unsigned char*)pvBufferIn,
(unsigned char*)pvBufferOut,
dwLength,
(AES_KEY*)&m_aesSecurityKey.getKey().front(),
state.ivec,
state.ecount,
&state.num,
(block128_f)AES_encrypt);
}
void CryptCTR::decryptCTR ( const char* pvBufferIn, char* pvBufferOut, unsigned long dwLength)
{
CRYPTO_ctr128_encrypt((const unsigned char*)pvBufferIn,
(unsigned char*)pvBufferOut,
dwLength,
(AES_KEY*)&m_aesSecurityKey.getKey().front(),
state.ivec,
state.ecount,
&state.num,
(block128_f)AES_encrypt);
}
If I encrypt decrypt and then decrypt once it works. But the problem starts when I try to do this:
// ENCODING //
{
for (int i=0;i<kStrVector.size();++i)
{
CryptCTR cryptCtr;
//SecurityKey aesExampleKey ( std::vector< char > (1) );
cryptCtr.initializeAesKey(/*&aesExampleKey*/);
const char* textToEncrypt = kStrVector.at(i).c_str();
auto output = cryptCtr.encrypt(textToEncrypt/*, aesExampleKey*/);
std::ofstream out("encoded-append.dat", std::ios::app);
for (const auto &e : output)
out << e;
out.close();
}
}
// DECODING //
{
CryptCTR cryptCtr;
std::ifstream t("encoded-append.dat");
std::stringstream buffer;
buffer << t.rdbuf();
std::string ss = buffer.str();
//SecurityKey aesExampleKey2 ( std::vector< char > (1) );
cryptCtr.initializeAesKey(/*&aesExampleKey2*/);
//initializeAesKey ( (const unsigned char*)CRYPT_AES_KEY, sizeof(CRYPT_AES_KEY) * 8, &aesExmapleKey2 );
auto output = cryptCtr.decrypt(buffer.str().c_str()/*, aesExampleKey2*/);
std::string s2(output.begin(), output.end());
std::ofstream out("decoded-append.dat");
out << s2;
out.close();
}
Then the program is able to decrypt only the text written in the first iteration.
Could you please tell me what I have wrong in my code?
Thanks in advance and regards
Upvotes: 0
Views: 623
Reputation: 104464
Shot in the dark guess, but encryption is typically binary. As such your encrypted output will have null char bytes inside it. So if you treat the encrypted data as a null terminated string, you risk losing data. Hence, your decrypt function should taking in a vector instead of a null terminated string.
Also, don't forget to pass ios_base::binary
into the constructor of your ifstream and ofstream constructors for reading/writing to your .dat file. This will be important if you want your code to run reliably on Windows.
Upvotes: 2