-2

I am working to encrypt and decrypt files using Crypto++. In encryption, key and random IV are generated and hexencoded where as text from file is encrypted. Both IV and cipher text are written to the same file.

In decryption, key is generated using same criteria as encryption and random IV is extracted from the file and hexdecoded. Text after iv length is stored in a string and decrypted.

What happens is I can see the original file so I know that it is working but it also displays cipher text after the original file text. Does any one how to solve it?

 //some code to declare variables, read from file and so on 

  unsigned char * inputContent = (unsigned char *) malloc(fileSize * sizeof(char));     //create char array of same size as file content 

 //inputContent is for storing file data    

  string rawString(reinterpret_cast<char*>(inputContent), fileSize);        //convert char array to string

  //extract iv, key and cipher from rawString
  string rawIV;
  rawIV = rawString.substr(0, 32);

  //code to hexdecode iv

  string cipher;
  cipher = rawString.substr(32, fileSize - 32);

  string recovered;

  CBC_Mode< AES >::Decryption d;
  d.SetKeyWithIV(key, sizeof(key), iv);

  StringSource s_recover(cipher, true, 
      new StreamTransformationFilter(d,
                new StringSink(recovered)
            )
        );  

  const char * writeContent = recovered.c_str();

  if(pwrite(fd, writeContent, recovered.length(), 0) <= 0)
  {
      return -1;    //error
  }

Thanks in advance. ☺

user4812502
  • 157
  • 1
  • 8
  • any specific reason you're using `pwrite`? – deW1 Apr 20 '15 at 23:23
  • @deW1 No. I tried using `write` but same result – user4812502 Apr 20 '15 at 23:25
  • Yeah just the file. But I need to add iv to the key after encryption and then extract it from file before decryption so I wasn't sure if `FileSource` would help – user4812502 Apr 21 '15 at 02:12
  • @jww Also I dont know how to use `FileSource` with integer file descriptor – user4812502 Apr 21 '15 at 18:13
  • @jww this project is more like a **change request**. File is already been read through different functions and in that function I am calling `encrypt(fd)` and `decrypt(fd)` – user4812502 Apr 21 '15 at 20:09
  • @jww I dont like mixing C and C++ either but I dont have any choice except for `read/pread` and `write/pwrite` but for **Crypto++** I have to convert them to string – user4812502 Apr 21 '15 at 20:12
  • @jww TBH, even I dont know the on-disk layout of the structure. I am new to programming in linux. But I am looking at the links you posted and see if that might help. Although, I can read the `iv` from the file and decrypt the file content, the problem is with writing to the file. Thanks for the link tho. If it helps, I am executing on a VM VirtualBox with default settings – user4812502 Apr 21 '15 at 20:37
  • @jww I am sorry if you think I am wasting your time. I am genuinely answering to the best of my knowledge. When encrypting, IV + cipher text is stored in the file. After `hexencoding` its 32 characters. So in `decrypt` function, I am reading first 32 characters and `hexdecoding` to regenerate same iv and the rest of the file content are cipher text. As for the `key`, it will be the same every time – user4812502 Apr 21 '15 at 20:53
  • @jww I wished you hadn't deleted the answer as it really contained some useful information for new learner. Maybe next time I ask a question, I could properly answer them. – user4812502 Apr 21 '15 at 21:16
  • @user4812502 - the answer was accumulating down votes. I suspect because its not clear what you are trying to do or what your problem is. There's no sense in leaving it up. Plus, you can find all the information on the [Crypto++ wiki](http://www.cryptopp.com/wiki/Main_Page). – jww Apr 21 '15 at 21:22
  • @jww So far it has accumulated exactly 1 nett downvote. You were a bit trigger-happy IMO. You should have more confidence. If you think it's correct, leave it there. Some people will downvote anything. – user207421 Apr 21 '15 at 23:53

1 Answers1

0

You might try something like this. But its hard to say if it will actually work since its not clear what you are actually doing or where the problem lies.

FileSource fs("<filename>", false /*pumpAll*/);    
SecByteBlock key(AES::DEFAULT_KEYLENGTH), iv(AES::BLOCKSIZE);

// Fetch key from somewhere
key = ...;

// Fetch IV from file
fs.Detach(new HexDecoder(new ArraySink(iv, iv.size()));
fs.Pump(32);

CBC_Mode< AES >::Decryption dec;
dec.SetKeyWithIV(key, key.size(), iv, iv.size());

string recovered;
fs.Detach(new HexDecoder(new StreamTransformationFilter(dec, new StringSink(recovered))));
fs.PumpAll();

You can also use the following if you get the SecByteBlockSink patch:

SecByteBlock recovered;
fs.Detach(new HexDecoder(new StreamTransformationFilter(dec, new SecByteBlockSink(recovered))));
fs.PumpAll();

rawString isn't needed below:

//create char array of same size as file content 
unsigned char * inputContent = (unsigned char *) malloc(fileSize * sizeof(char));     

//inputContent is for storing file data    

//convert char array to string
string rawString(reinterpret_cast<char*>(inputContent), fileSize);

Maybe you should try:

ArraySource as(inputContent, fileSize, false /*pumpAll*/);

Using the ArraySource means you don't make a copy of the data (the string copies the data), and its ready to go for Crypto++.

Also, since you're already into C++ code, use an unique_ptr and new rather than malloc. The unique_ptr will handle cleanup for you. (Or, use a std::vector).

unique_ptr<byte[]> buffer(new byte[fileSize]);

I don't know how you are going to make a file descriptor work in the grand scheme of things. Crypto++ is a C++ library, and C++ uses I/O streams. Maybe this will help: How to construct a c++ fstream from a POSIX file descriptor?

Also see Retrieving file descriptor from a std::fstream and Getting a FILE* from a std::fstream.

Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885