Serialization encryption c# [duplicate] - c#

This question already has answers here:
C# Encrypt serialized file before writing to disk
(4 answers)
Closed 5 years ago.
I use Serialize function to save an object to hard disk by the following code:
using (FileStream fs = new FileStream(fileName, FileMode.Create))
new BinaryFormatter().Serialize(fs, myObject);
Then I reload it again when I need it:
using(FileStream fs = new FileStream(fileName, FileMode.Open))
myObject = (Templates)new BinaryFormatter().Deserialize(fs);
I'm searching an easy way to encrypt the file I save to protect it and also fast way because the time factor in saving and reading the file is very important.
Any suggestions please, thank you in advance!

You're probably looking for something like this:
Aes aes = Aes.Create();
aes.Key = yourByteArrayKey;
aes.IV = yourByteArrayIV;
// Save
using (FileStream fs = new FileStream(fileName, FileMode.Create)) {
using (CryptoStream cs = new CryptoStream(fs, aes.CreateEncryptor(), CryptoStreamMode.Write)) {
new BinaryFormatter().Serialize(cs, myObject);
}
}
// Load
using (FileStream fs = new FileStream(fileName, FileMode.Open)) {
using (CryptoStream cs = new CryptoStream(fs, aes.CreateEncryptor(), CryptoStreamMode.Read)) {
myObject = (Templates)new BinaryFormatter().Deserialize(cs);
}
}
You can use any other algorithm as long as it can return an ICrytoTransform, like the aes.CreateEncryptor() method (which is inherited from SymmetricAlgorithm)

Related

HowTo lock a file, read its content and overwrite it? [duplicate]

This question already has answers here:
How to both read and write a file in C#
(6 answers)
Closed 5 years ago.
I need to read the content of a file and overwrite it while the file is locked. I don't want the file to be unlocked between read and write operations.
using (var file = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
using (var reader = new StreamReader(file, Encoding.Unicode))
using (var writer = new StreamWriter(file, Encoding.Unicode))
{
// read
// calculate new content
// overwrite - how do I do this???
}
}
If I use two FileStreams, the file is cleared when instantiating the writer but the file will be briefly unlocked between the reader and writer instantiation.
using (var reader = new StreamReader(new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.None)))
{
// read
// calculate new content
}
using (var writer = new StreamWriter(new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)))
{
// write
}
If you keep open the original FileStream you can do it:
using (var file = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
// This overload will leave the underlying stream open
using (var reader = new StreamReader(file, Encoding.Unicode, true, 4096, true))
{
//Read
}
file.SetLength(0); //Truncate the file and seek to 0
using (var writer = new StreamWriter(file, Encoding.Unicode))
{
//Write the new data
}
}

Serializing object at specific byte index

In VS2015, I would like to serialize a data table to a file, beginning at byte 16, since the file is to be encrypted and the IV uses the bytes 0-15. I have not yet found a serialization method taking an offset parameter, so should I convert the table to a byte array? There must be a cleaner approach. Here is one of the functions:
internal static void EncryptData(DataTable dTable, string userName, string password, string fileName)
{
using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
{
using (Aes aes = SetAes(userName, password)) // simply performs aes initialization
{
fs.Write(aes.IV, 0, 16); // writing the IV
using (CryptoStream cs = new CryptoStream(fs, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
dTable.WriteXml(cs, XmlWriteMode.WriteSchema); // This is overwriting the bytes 0-15 :(
}
}
}
}
EDIT: Adding deserialization function, which throws the exception "Length of the data to decrypt is invalid"
internal static void DecryptData(DataTable dTable, string userName, string password, string fileName)
{
using (FileStream fs = new FileStream(fileName, FileMode.Open))
{
byte[] IV = new byte[16];
fs.Read(IV, 0, 16);
using (Aes aes = SetAes(userName, password, IV)) // simply setting aes
{
using (CryptoStream cs = new CryptoStream(fs, aes.CreateDecryptor(), CryptoStreamMode.Read))
{
dTable.ReadXml(cs);
}
}
}
}
FINAL EDIT: The solution: Add IV bytes with File.WriteAllBytes and use FileStream filemode.Append in the serializing method(EncryptData):
using (Aes aes = SetAes(userName, password))
{
File.WriteAllBytes(fileName, aes.IV);
using (FileStream fs = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.None))
{
using (CryptoStream cs = new CryptoStream(fs, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
dTable.WriteXml(cs, XmlWriteMode.WriteSchema);
}
}
}

Serialize, Compress and Encrypt in C#

I want to write a C# class that can serialize, compress and encrypt objects, in that order. I need the resulting file to
Be created as fast as possible
Take as little space as possible
Be as unreadable as possible
I've been researching and coding for a while and this is what I have.
private void SaveObject(string path, object obj)
{
using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
{
string password = "123";
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
RijndaelManaged RMCrypto = new RijndaelManaged();
using (CryptoStream cryptoStream = new CryptoStream(fileStream, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write))
using (var gZipStream = new GZipStream(cryptoStream, CompressionMode.Compress))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(gZipStream, obj);
}
}
}
private void LoadObject(string path, out object obj)
{
using (FileStream fileStream = new FileStream(path, FileMode.Open))
{
string password = "123";
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
RijndaelManaged RMCrypto = new RijndaelManaged();
using (CryptoStream cryptoStream = new CryptoStream(fileStream, RMCrypto.CreateDecryptor(key, key), CryptoStreamMode.Read))
using (var gZipStream = new GZipStream(cryptoStream, CompressionMode.Decompress))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
obj = binaryFormatter.Deserialize(gZipStream);
}
}
}
I'm an amateur programmer and I have little knowledge about serialization, streams and encryption. I was even surprised this worked without a problem. My question is: Does this code follow the best programming practice and achieve the goals sufficiently without wasting time or resources?
Note: This is a generic method that I will use in my programs to store data locally.
take a look at https://github.com/HansHinnekint/EncryptionLib. The InfoBlockConvertor code of https://github.com/HansHinnekint/EncryptionLib/blob/master/EncryptionLibrary/InfoBlockConvertor.cs can be used as sample.
Only the compression needs to be added later on. That should not be that difficult.

How do I convert this to read a zip file? [duplicate]

This question already has answers here:
Unzipping a .gz file using C#
(3 answers)
Closed 8 years ago.
I am reading an unzipped binary file from disk like this:
string fn = #"c:\\MyBinaryFile.DAT";
byte[] ba = File.ReadAllBytes(fn);
MemoryStream msReader = new MemoryStream(ba);
I now want to increase speed of I/O by using a zipped binary file. But how do I fit it into the above schema?
string fn = #"c:\\MyZippedBinaryFile.GZ";
//Put something here
byte[] ba = File.ReadAllBytes(fn);
//Or here
MemoryStream msReader = new MemoryStream(ba);
What is the best way to achieve this pls.
I need to end up with a MemoryStream as my next step is to deserialize it.
You'd have to use a GZipStream on the content of your file.
So basically it should be like this:
string fn = #"c:\\MyZippedBinaryFile.GZ";
byte[] ba = File.ReadAllBytes(fn);
using (MemoryStream msReader = new MemoryStream(ba))
using (GZipStream zipStream = new GZipStream(msReader, CompressionMode.Decompress))
{
// Read from zipStream instead of msReader
}
To account for the valid comment by flindenberg, you can also open the file directly without having to read the entire file into memory first:
string fn = #"c:\\MyZippedBinaryFile.GZ";
using (FileStream stream = File.OpenRead(fn))
using (GZipStream zipStream = new GZipStream(stream, CompressionMode.Decompress))
{
// Read from zipStream instead of stream
}
You need to end up with a memory stream? No problem:
string fn = #"c:\\MyZippedBinaryFile.GZ";
using (FileStream stream = File.OpenRead(fn))
using (GZipStream zipStream = new GZipStream(stream, CompressionMode.Decompress))
using (MemoryStream ms = new MemoryStream()
{
zipStream.CopyTo(ms);
ms.Seek(0, SeekOrigin.Begin); // don't forget to rewind the stream!
// Read from ms
}

How do I use C# to encrypt another program?

SO, in Visual C#.NET I would like it to somehow be able to taken in a program (through an open file dialog), then somehow take the bytes of that program and encrypt the bytes, to be executed later.
How would I do that? How would I encrypt, then later decrypt, a program using Visual C#.NET?
This answer shows you how to execute a byte array. One caution, this may cause problems with virus scanners because it is common in malware.
If you don't want to execute from memory, I whipped up an example of how you could encrypt store then decrypt and run an executable.
public class FileEncryptRunner
{
Byte[] key = ASCIIEncoding.ASCII.GetBytes("thisisakeyzzzzzz");
Byte[] IV = ASCIIEncoding.ASCII.GetBytes("thisisadeltazzzz");
public void SaveEncryptedFile(string sourceFileName)
{
using (FileStream fStream = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read),
outFStream = new FileStream(Environment.SpecialFolder.MyDocuments+"test.crp", FileMode.Create))
{
Rijndael RijndaelAlg = Rijndael.Create();
using (CryptoStream cStream = new CryptoStream(outFStream, RijndaelAlg.CreateEncryptor(key, IV), CryptoStreamMode.Write))
{
StreamWriter sWriter = new StreamWriter(cStream);
fStream.CopyTo(cStream);
}
}
}
public void ExecuteEncrypted()
{
using (FileStream fStream = new FileStream(Environment.SpecialFolder.MyDocuments + "test.crp", FileMode.Open, FileAccess.Read, FileShare.Read),
outFStream = new FileStream(Environment.SpecialFolder.MyDocuments + "crpTemp.exe", FileMode.Create))
{
Rijndael RijndaelAlg = Rijndael.Create();
using (CryptoStream cStream = new CryptoStream(fStream, RijndaelAlg.CreateDecryptor(key, IV), CryptoStreamMode.Read))
{ //Here you have a choice. If you want it to only ever exist decrypted in memory then you have to use the method in
// the linked answer.
//If you want to run it from a file than it's easy and you save the file and run it, this is simple.
cStream.CopyTo(outFStream);
}
}
Process.Start(Environment.SpecialFolder.MyDocuments + "crpTemp.exe");
}
}

Categories

Resources