CryptoStream?

W

weixiang

Hi,

I want to use DES and CryptoStream to serialize a encrypted stream to a file
with a header "CRYPT". And I wrote these code:

To store:

FileStream fileStream = new FileStream(fileName, FileMode.Create,
FileAccess.Write, FileShare.None);
byte[] signture = AE.GetBytes("CRYPT");
fileStream.Write(signture, 0, 5);

ICryptoTransform ct = des.CreateDecryptor(key, iv);
CryptoStream cryptoStream = new CryptoStream(fileStream, ct,
CryptoStreamMode.Write);

IFormatter formatter = new BinaryFormatter();
formatter.Binder = new DataSNBinder();
formatter.Serialize(cryptoStream, MYDATA);

cryptoStream.Flush();
fileStream.Close();

To load:

FileStream fileStream = new FileStream(fileName, FileMode.Open,
FileAccess.Read);
fileStream.Seek(5, SeekOrigin.Begin);
ICryptoTransform ct = des.CreateDecryptor(key, iv);
CryptoStream cryptoStream = new CryptoStream(fileStream, ct,
CryptoStreamMode.Read);
formatter = new BinaryFormatter();
formatter.Binder = new DataSNBinder();
MYDATA = (MYDATA)formatter.Deserialize(cryptoStream);
cryptoStream.Close();

And with that code I can not load the saved file. What's the problem?

And, what's the exact meaning of CryptoStream.Close()? If I replace the
CryptoStream.Flush() with Close(), it will crash. But the encrypted file
size is somewhat smaller than the original data size, is that mean a problem
in my code?

Thank you very much
weixiang
 
W

weixiang

Thank you. I'll test that ASAP.

What's the CryptoStream.Close() mean? It will throw a exception if I use
that to instead CryptoStream.Flush()

Rob Teixeira said:
I haven't run the code, but I immediately noticed something that needs to
get fixed.
After the last write into the CrypoStream, you MUST call FlushFinalBlock
(not Flush).
The final block of cypher data must be properly padded according to the
cypher, otherwise, you can't decrypt.

-Rob [MVP]

weixiang said:
Hi,

I want to use DES and CryptoStream to serialize a encrypted stream to a file
with a header "CRYPT". And I wrote these code:

To store:

FileStream fileStream = new FileStream(fileName, FileMode.Create,
FileAccess.Write, FileShare.None);
byte[] signture = AE.GetBytes("CRYPT");
fileStream.Write(signture, 0, 5);

ICryptoTransform ct = des.CreateDecryptor(key, iv);
CryptoStream cryptoStream = new CryptoStream(fileStream, ct,
CryptoStreamMode.Write);

IFormatter formatter = new BinaryFormatter();
formatter.Binder = new DataSNBinder();
formatter.Serialize(cryptoStream, MYDATA);

cryptoStream.Flush();
fileStream.Close();

To load:

FileStream fileStream = new FileStream(fileName, FileMode.Open,
FileAccess.Read);
fileStream.Seek(5, SeekOrigin.Begin);
ICryptoTransform ct = des.CreateDecryptor(key, iv);
CryptoStream cryptoStream = new CryptoStream(fileStream, ct,
CryptoStreamMode.Read);
formatter = new BinaryFormatter();
formatter.Binder = new DataSNBinder();
MYDATA = (MYDATA)formatter.Deserialize(cryptoStream);
cryptoStream.Close();

And with that code I can not load the saved file. What's the problem?

And, what's the exact meaning of CryptoStream.Close()? If I replace the
CryptoStream.Flush() with Close(), it will crash. But the encrypted file
size is somewhat smaller than the original data size, is that mean a problem
in my code?

Thank you very much
weixiang
 
R

Rob Teixeira [MVP]

Close will close the CryptoStream and the underlying stream object the
CryptoStream is writing to.
In accordance to stream behavior, Close calls Flush, but in this case, you
need to call FlushFinalBlock.

-Rob [MVP]

weixiang said:
Thank you. I'll test that ASAP.

What's the CryptoStream.Close() mean? It will throw a exception if I use
that to instead CryptoStream.Flush()

Rob Teixeira said:
I haven't run the code, but I immediately noticed something that needs to
get fixed.
After the last write into the CrypoStream, you MUST call FlushFinalBlock
(not Flush).
The final block of cypher data must be properly padded according to the
cypher, otherwise, you can't decrypt.

-Rob [MVP]

weixiang said:
Hi,

I want to use DES and CryptoStream to serialize a encrypted stream to
a
file
with a header "CRYPT". And I wrote these code:

To store:

FileStream fileStream = new FileStream(fileName, FileMode.Create,
FileAccess.Write, FileShare.None);
byte[] signture = AE.GetBytes("CRYPT");
fileStream.Write(signture, 0, 5);

ICryptoTransform ct = des.CreateDecryptor(key, iv);
CryptoStream cryptoStream = new CryptoStream(fileStream, ct,
CryptoStreamMode.Write);

IFormatter formatter = new BinaryFormatter();
formatter.Binder = new DataSNBinder();
formatter.Serialize(cryptoStream, MYDATA);

cryptoStream.Flush();
fileStream.Close();

To load:

FileStream fileStream = new FileStream(fileName, FileMode.Open,
FileAccess.Read);
fileStream.Seek(5, SeekOrigin.Begin);
ICryptoTransform ct = des.CreateDecryptor(key, iv);
CryptoStream cryptoStream = new CryptoStream(fileStream, ct,
CryptoStreamMode.Read);
formatter = new BinaryFormatter();
formatter.Binder = new DataSNBinder();
MYDATA = (MYDATA)formatter.Deserialize(cryptoStream);
cryptoStream.Close();

And with that code I can not load the saved file. What's the problem?

And, what's the exact meaning of CryptoStream.Close()? If I replace the
CryptoStream.Flush() with Close(), it will crash. But the encrypted file
size is somewhat smaller than the original data size, is that mean a problem
in my code?

Thank you very much
weixiang
 
S

Simon Trew

So why doesn't Close call FlushFinalBlock? Why would you ever not want it
to?

S.
 
W

weixiang

I tried to call FlushFinalBlock to instead Flush, but it still throw a
exception that said "Length of the data to decrypt is invalid". Is there
other problem? And I believe I am going to encrypt my data, not to decrypt
it. Is that declared in the CryptoStream constructor with CSMode.Write?

Here is my current code:

FileStream fileStream = new FileStream(fileName, FileMode.Create,
FileAccess.Write, FileShare.None);
byte[] signture = AE.GetBytes("CRYPT");
fileStream.Write(signture, 0, 5);

ICryptoTransform ct = des.CreateDecryptor(key, iv);
CryptoStream cryptoStream = new CryptoStream(fileStream, ct,
CryptoStreamMode.Write);

IFormatter formatter = new BinaryFormatter();
formatter.Binder = new DataSNBinder();
formatter.Serialize(cryptoStream, MYDATA);

cryptoStream.FlushFinalBlock(); // throw exception here
fileStream.Close();
 
R

Rob Teixeira [MVP]

OK, instead of trying to wade through the code, I wrote my own ;-)
This sample includes just about everything you need. I'm serializing a
string object, but that could easily be any object.

byte[] key = new byte[8];

byte[] iv = new byte[8];

FileStream fs = null;

CryptoStream cs = null;

BinaryFormatter bf = null;

string myData = "This is some test data.";

string myData2 = string.Empty;

DES desCypher = DES.Create();

// Encryption starts here

try

{

// create some key and IV data for the sample

RandomNumberGenerator.Create().GetBytes(key);

RandomNumberGenerator.Create().GetBytes(iv);

fs = new FileStream(@"C:\sample.dat", FileMode.OpenOrCreate);

fs.Write(Encoding.ASCII.GetBytes("CRYPT"), 0, 5);

cs = new CryptoStream(fs, desCypher.CreateEncryptor(key, iv),
CryptoStreamMode.Write);

bf = new BinaryFormatter();

bf.Serialize(cs, myData);

cs.FlushFinalBlock();

}

catch (Exception ex)

{

MessageBox.Show(ex.ToString());

}

finally

{

if (cs != null) cs.Close();

}

// decryption starts here

try

{

fs = new FileStream(@"C:\sample.dat", FileMode.Open);

fs.Position = 5;

cs = new CryptoStream(fs, desCypher.CreateDecryptor(key, iv),
CryptoStreamMode.Read);

myData2 = bf.Deserialize(cs) as string;

MessageBox.Show(myData2);

}

catch (Exception ex)

{

MessageBox.Show(ex.ToString());

}

finally

{

if (cs != null) cs.Close();

}

-Rob [MVP]


weixiang said:
I tried to call FlushFinalBlock to instead Flush, but it still throw a
exception that said "Length of the data to decrypt is invalid". Is there
other problem? And I believe I am going to encrypt my data, not to decrypt
it. Is that declared in the CryptoStream constructor with CSMode.Write?

Here is my current code:

FileStream fileStream = new FileStream(fileName, FileMode.Create,
FileAccess.Write, FileShare.None);
byte[] signture = AE.GetBytes("CRYPT");
fileStream.Write(signture, 0, 5);

ICryptoTransform ct = des.CreateDecryptor(key, iv);
CryptoStream cryptoStream = new CryptoStream(fileStream, ct,
CryptoStreamMode.Write);

IFormatter formatter = new BinaryFormatter();
formatter.Binder = new DataSNBinder();
formatter.Serialize(cryptoStream, MYDATA);

cryptoStream.FlushFinalBlock(); // throw exception here
fileStream.Close();


Simon Trew said:
So why doesn't Close call FlushFinalBlock? Why would you ever not want it
to?

S.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top