0

I'm using the code bellow to Encrypt and Decrypt a file:

// Encryption

UnicodeEncoding UE = new UnicodeEncoding();

byte[] key = UE.GetBytes("password");

FileStream fsCrypt = new FileStream("cryptFile", FileMode,create);

RijndaelManaged RMCrypto = new RijndaelManaged();

CryptoStream cs = new CryptoStream(fsCrypt,
                RMCrypto.CreateEncryptor(key, key),
                CryptoStreamMode.Write);

FileStream fsIn = new FileStream("FileName", FileMode.Open);

int data;
while ((data = fsIn.ReadByte()) != -1)
      cs.WriteByte((byte)data);

fsIn.Close();
cs.Close();
fsCrypt.Close();

// Decryption

UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes("password");

FileStream fsCrypt = new FileStream("filename", FileMode.Open);

RijndaelManaged RMCrypto = new RijndaelManaged();

CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateDecryptor(key, key),
CryptoStreamMode.Read);

int data;
while ((data = cs.ReadByte()) != -1)
     memorystream.WriteByte((byte)data);

It works well, without any problem!

For some reasons I've added 10 bytes at the first of the encrypted file! Actually I've created a 10 bytes file (the file size is EXACTLY 10 Bytes), then I've appended the encrypted file to this file.

Note that the 10 bytes file is not encrypted, and is created using simple filestream, and it could be read in notepad.

Now in decryption code, how could I eliminate the first 10 bytes and decrypt remain data in the file?

I've tried to call ReadByte() for 10 times, and then goto the WHILE part and decrypt file, but it doesn't work and I get length invalid exception.

Thanks in advance.

Muhamad Jafarnejad
  • 2,521
  • 4
  • 21
  • 34
  • Did you try calling fsCrypt.ReadByte() 10 times, before opening the CryptoStream over it? – canton7 Feb 10 '15 at 14:50
  • Yes I did. I've mentioned in my question above. It doesn't work. It seems that fsCrypt.ReadByte is different from simple fileStream readByte() ! – Muhamad Jafarnejad Feb 11 '15 at 05:46
  • You said "I've tried to call ReadByte() for 10 times" - you didn't say what you called it *on* - there are lots of streams in there. fsCrypt *is* a FileStream - I don't know what you mean when you say it must be different. Anyway, time to break out the debugger. Verify that the contents of 'fsCrypt' in your first snippet match the contents of 'fsCrypt' in the second snippet *after* reading 10 bytes. Don't try and decrypt it yet, just make sure you're looking at the bytes you expect. – canton7 Feb 11 '15 at 10:14
  • I'm sorry, I've misunderstood. YES, absolutely correct. calling readbyte() before sending the FileStream to CryptoStream is the answer. Thanks alot for that. how could I mark it as answer? could you send it in the answer and let me mark it. thanks again :) – Muhamad Jafarnejad Feb 11 '15 at 21:16

1 Answers1

2

Posting my comment as an answer as requested.

You say

I've tried to call ReadByte() for 10 times, and then goto the WHILE part and decrypt file, but it doesn't work and I get length invalid exception.

but you don't say exactly which stream you call ReadByte() 10 times on, and when exactly you call it.

Make sure you're calling it on fsCrypt before you instantiate the new CryptoStream.

Note also that that you can probably just call fsCrypt.Position = 10; or fsCrypt.Seek(10, SeekOrigin.Begin), instead of reading 10 dummy bytes, since FileStream supports seeking.

For example:

byte[] key = Encoding.Unicode.GetBytes("password");

FileStream fsCrypt = File.OpenRead("filename");
fsCrypt.Position = 10; // Skip the 10 useless bytes at the start

RijndaelManaged rijndaelManaged = new RijndaelManaged();

// Disposing CryptoStream will also dispose the FileStream passed to it
using (CryptoStream cryptoStream = new CryptoStream(fsCrypt, rijndaelManaged.CreateDecryptor(key, key), CryptoStreamMode.Read))
{
    cryptoStream.CopyTo(memoryStream);
}

As an aside: DO NOT USE THE KEY AS THE IV!

The IV needs to be different every time you encrypt something, but can be public. A common technique is to randomly generate an IV every time you want to encrypt something, and put it as the first N bytes of the encrypted stream. When it comes to decrypting, read the first N bytes of the encrypted stream yourself (before creating the CryptoStream), set that as the IV, open the CryptoStream, and read the rest.

canton7
  • 37,633
  • 3
  • 64
  • 77