Search code examples
c++fileencryptionofstream

C++ ofstream output file does not equal output to file


I am using a simple algorithm to encrypt a text document. It's working fine for the first 120 characters. My problem is the difference between console output and encrypted content written in the output file. Can you please help me?

#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <fstream>
#include <string>
#include <stdio.h>
using namespace std;

int main() {
int Ra;
string filename;
cout<< "enter file name to encrypt"<<endl;
getline(cin,filename);
filename.append(".txt");
string line;
string page;
 ifstream infile;
infile.open (filename.c_str());
if (infile.is_open())
{
 while ( getline (infile,line) )
 {
   cout << endl<<line << '\n';
 page=page+line;
}
infile.close();
}
else
{cout << "Unable to open file";
exit(1);}
char page2[page.length()];
//convert string to char
for (int a=0;a<=page.length()-1;a++)
    {
        page2[a]=page[a];

    }
char output[page.length()];

srand (time(NULL));
int seed=rand() % 99900000;

srand (seed);
//encrypt
for(int b=0;b<=page.length()-1;b++){
Ra=rand() % 1000;
output[b]=page2[b]+Ra;
cout<<b<<","<<page[b]<<","<<page2[b]<<","<<output[b]<<endl;
}

//display+put back
cout<<"output encrypted"<<endl;
ofstream outfile ;
outfile.open (filename.c_str(),ios::trunc);
if (outfile.is_open()){
    cin.sync();
for (int c=0;c<=page.length()-1;c++){
cout<<output[c]<<", ";
outfile<<output[c];
    }
 outfile.close();
}
else cout << "Unable to open file";
cout<<endl<<"key= "<<seed;
cout << endl << "Press any key to continue...";
cin.sync();
cin.ignore();
return 0;
}

original text doc

output and final result not equal


Solution

  • char page2[page.length()]; //?
    //convert string to char
    for (int a=0;a<=page.length()-1;a++) page2[a]=page[a];
    char output[page.length()];
    

    You don't need this to convert string to char array. page already holds the characters in an array. If you like you can use std::string page2 = page; and std::string output = page;

    Ra=rand() % 1000;
    output[b]=page2[b]+Ra;
    

    Each byte holds a value between 0 to 255. If you add a random value up to 1000 then you will not be able to reverse the operation.

    In this ghetto encryption scheme you don't want to exceed the char limit. You can use the ^ operator instead. Then write the encrypted data in binary format:

    srand(seed);
    string output = page;
    for(size_t b = 0; b < page.length(); b++)
        output[b] ^= (rand() % 0xFF);
    
    ofstream outfile("encrypted.binary", ios::binary);
    outfile.write(output.data(), output.size());
    outfile.close();
    

    Then you can read the data again (in binary) and use the XOR operator once more:

    std::string decrypt = output;
    srand(seed);
    for(size_t b = 0; b < page.length(); b++)
        decrypt[b] ^= (rand() % 0xFF);
    
    ofstream filedecrypt("decrypted.txt");
    filedecrypt.write(decrypt.data(), decrypt.size());
    filedecrypt.close();
    

    Edit:

    Note that this is "obfuscation" not encryption. It also requires that program is made by the same compiler/machine so that the repetition in rand can be duplicated.

    For actual encryption you can study AES. In simplest explanation, AES uses a key. This key is sort of like a password, but it's up to 32 bytes long, and it doesn't go from A to Z, it goes from 0 to 255.

    AES uses they key, plus secure random number generator, to create an encryption block 16 bytes in length, lets say these random bytes:

    {29, 23, BE, 84, E1, 6C, D6, AE, 52, 90, 49, F1, F1, BB, E9, EB}
    

    Then XOR that with plain text to create secret text. AES will then make another 16 byte encryption block based on the previous block, the previous 16 bytes of plain text, and the secret key.

    In simplest way, this is somewhat similar to what you are doing, but instead of getting one byte rand(), it get of 16 bytes from aes(). The sequence from AES cannot be predicate (except brute force attack which take a million years)

    Use libraries like OpenSSL to implement AES encryption.