How to encrypt and save a binary stream after serialization and read it back?
- by Anindya Chatterjee
I am having some problems in using CryptoStream when I want to encrypt a binary stream after binary serialization and save it to a file. I am getting the following exception
System.ArgumentException : Stream was not readable.
Can anybody please show me how to encrypt a binary stream and save it to a file and deserialize it back correctly?
The code is as follows:
class Program
{
public static void Main(string[] args)
{
var b = new B {Name = "BB"};
WriteFile<B>(@"C:\test.bin", b, true);
var bb = ReadFile<B>(@"C:\test.bin", true);
Console.WriteLine(b.Name == bb.Name);
Console.ReadLine();
}
public static T ReadFile<T>(string file, bool decrypt)
{
T bObj = default(T);
var _binaryFormatter = new BinaryFormatter();
Stream buffer = null;
using (var stream = new FileStream(file, FileMode.OpenOrCreate))
{
if(decrypt)
{
const string strEncrypt = "*#4$%^.++q~!cfr0(_!#$@$!&#&#*&@(7cy9rn8r265&$@&*E^184t44tq2cr9o3r6329";
byte[] dv = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
CryptoStream cs;
DESCryptoServiceProvider des = null;
var byKey = Encoding.UTF8.GetBytes(strEncrypt.Substring(0, 8));
using (des = new DESCryptoServiceProvider())
{
cs = new CryptoStream(stream, des.CreateEncryptor(byKey, dv), CryptoStreamMode.Read);
}
buffer = cs;
}
else
buffer = stream;
try
{
bObj = (T) _binaryFormatter.Deserialize(buffer);
}
catch(SerializationException ex)
{
Console.WriteLine(ex.Message);
}
}
return bObj;
}
public static void WriteFile<T>(string file, T bObj, bool encrypt)
{
var _binaryFormatter = new BinaryFormatter();
Stream buffer;
using (var stream = new FileStream(file, FileMode.Create))
{
try
{
if(encrypt)
{
const string strEncrypt = "*#4$%^.++q~!cfr0(_!#$@$!&#&#*&@(7cy9rn8r265&$@&*E^184t44tq2cr9o3r6329";
byte[] dv = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
CryptoStream cs;
DESCryptoServiceProvider des = null;
var byKey = Encoding.UTF8.GetBytes(strEncrypt.Substring(0, 8));
using (des = new DESCryptoServiceProvider())
{
cs = new CryptoStream(stream, des.CreateEncryptor(byKey, dv), CryptoStreamMode.Write);
buffer = cs;
}
}
else
buffer = stream;
_binaryFormatter.Serialize(buffer, bObj);
buffer.Flush();
}
catch(SerializationException ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
[Serializable]
public class B
{
public string Name {get; set;}
}
It throws the serialization exception as follows
The input stream is not a valid binary format. The starting contents (in bytes)
are: 3F-17-2E-20-80-56-A3-2A-46-63-22-C4-49-56-22-B4-DA ...