Reputation: 843
I have a requirement where I have to create a Tab delimited file encrypted. The other requirement is also to take the encrypted and decrypt the file and read the file lines. Ideally I would like only to save an encrypted file and not the unencrypted file in a streaming process.
For the encrypted I will have a main method which will create the strings (lines strings) and pass them to an method which encrypts and save to the file. The below code is what I have written.
public bool EncryptFileString(string inputString, string outputFile)
{
try
{
string cryptFile = outputFile;
FileStream fsCrypt = new FileStream(cryptFile, FileMode.OpenOrCreate, FileAccess.Write);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateEncryptor(this.keyPhrase, this.initializationVector),
CryptoStreamMode.Write);
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(inputString));
int data;
while ((data = ms.ReadByte()) != -1)
cs.WriteByte((byte)data);
cs.Close();
fsCrypt.Close();
cs.Dispose();
fsCrypt.Dispose();
return true;
}
catch (Exception de)
{
return false;
//TODO : Log
}
}
For the decryption I have no idea how to get this done. What I have been able to get is the below. In the example i am trying to just decrypt the file and save it in another file, but ideally would like to stream lines instead of saving the unencrypted file and then reading it.
public bool DecryptFile(string inputFile, string outputFile)
{
try
{
FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateDecryptor(this.keyPhrase, this.initializationVector),
CryptoStreamMode.Read);
List<byte> fsOut = new List<byte>();// new FileStream(outputFile, FileMode.Create);
int data;
while ((data = cs.ReadByte()) != -1)
fsOut.Add((byte)data);
//fsOut.WriteByte((byte)data);
//fsOut.Close();
cs.Close();
fsCrypt.Close();
var str = Encoding.UTF8.GetString(fsOut.ToArray());
File.WriteAllText(outputFile,str);
return true;
}
catch (Exception de)
{
return false;
//TODO : Log
}
}
When i am testing this, i call the encryption method passing a file strings and saving it and then the decryption is called. But the resultant file is missing 2 lines on the top and could not also decrypt few character (for example i have : and / (like "https")).
I get samples to encrypt the file (and it works) where input and output file is both saved to disk. But did not find anything which deals with strings and files.
Any suggestions is welcome.
Upvotes: 1
Views: 1100
Reputation: 12341
Try this (improve with what you have with checks, try/catch etc)
private static string key = "";
private static string iv = "";
private static readonly string someString = "The quick brown fox jumps over the lazy dogs";
private static readonly string targetFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "encrypted.txt");
static void Main(string[] args)
{
GenerateKeyIv();
EncryptToFile();
var decryptedFile = DecryptFile();
Console.WriteLine(decryptedFile);
}
static void EncryptToFile()
{
using (var rijndeal = new RijndaelManaged { Key = Convert.FromBase64String(key), IV = Convert.FromBase64String(iv) })
{
var encryptor = rijndeal.CreateEncryptor(rijndeal.Key, rijndeal.IV);
using var fs = new FileStream(targetFile, FileMode.Create);
//write to Filestream
using (CryptoStream cs = new CryptoStream(fs, encryptor, CryptoStreamMode.Write))
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(someString);
}
}
}
static string DecryptFile()
{
using (var rijndeal = new RijndaelManaged { Key = Convert.FromBase64String(key), IV = Convert.FromBase64String(iv) })
{
var encryptor = rijndeal.CreateDecryptor(rijndeal.Key, rijndeal.IV);
using var fs = new FileStream(targetFile, FileMode.Open);
//read from FileStream
using (CryptoStream cs = new CryptoStream(fs, encryptor, CryptoStreamMode.Read))
using (StreamReader sr = new StreamReader(cs))
{
return sr.ReadToEnd();
}
}
}
/// <summary>
/// Sample creating Key and IV
/// The same Key/IV used to encrypt must be used to decrypt
/// To use the same key/iv for encrypting/decrypting to/from file, persist these somewhere for reuse (this sample creates them on each run)
/// </summary>
static void GenerateKeyIv()
{
using (var rijndael = new RijndaelManaged())
{
rijndael.GenerateIV();
rijndael.GenerateKey();
key = Convert.ToBase64String(rijndael.Key);
iv = Convert.ToBase64String(rijndael.IV);
}
}
Hth..
Upvotes: 1