Encrypting (Appended) text file

I need to append a txt file every minute or so..
I have to encrypt the line before saving. The new line will have line breaks...and the routine must support all chars.

I can encrypt it using:

private static string ES(string InputText, string Password)

{

RijndaelManaged RijndaelCipher = new RijndaelManaged();

// First we need to turn the input strings into a byte array.

byte[] PlainText = System.Text.Encoding.Unicode.GetBytes(InputText);

// We are using salt to make it harder to guess our key

// using a dictionary attack.

byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());

// The (Secret Key) will be generated from the specified

// password and salt.

PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);

// Create a encryptor from the existing SecretKey bytes.

// We use 32 bytes for the secret key

// (the default Rijndael key length is 256 bit = 32 bytes) and

// then 16 bytes for the IV (initialization vector),

// (the default Rijndael IV length is 128 bit = 16 bytes)

ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));

// Create a MemoryStream that is going to hold the encrypted bytes

MemoryStream memoryStream = new MemoryStream();

// Create a CryptoStream through which we are going to be processing our data.

// CryptoStreamMode.Write means that we are going to be writing data

// to the stream and the output will be written in the MemoryStream

// we have provided. (always use write mode for encryption)

CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);

// Start the encryption process.

cryptoStream.Write(PlainText, 0, PlainText.Length);

// Finish encrypting.

cryptoStream.FlushFinalBlock();

// Convert our encrypted data from a memoryStream into a byte array.

byte[] CipherBytes = memoryStream.ToArray();

// Close both streams.

memoryStream.Close();

cryptoStream.Close();

// Convert encrypted data into a base64-encoded string.

// A common mistake would be to use an Encoding class for that.

// It does not work, because not all byte values can be

// represented by characters. We are going to be using Base64 encoding

// That is designed exactly for what we are trying to do.

string EncryptedData = Convert.ToBase64String(CipherBytes);

// Return encrypted string.

return EncryptedData;

}

The problem is decrypting the file to read.

The decrypt routine crashes...
Im reading the file line by line...

Can someone point me in the right direction





Answer this question

Encrypting (Appended) text file

  • jmoser

    bump

  • Sid463

    There are a few problems with encrypting data to a text file first. What I beleive is happening is, you are using a CryptoStream to write a series of strings to a text file. After the CryptoStream encrypts it, a line break is being added. The problem with that is, because the CryptoStream didn't generate the breaks itself, it finds that as a fault.

    What I did is I wrote a Console Application that read/writes to a log file, but instead of using a Unicode document, it converts the encrypted bytes to a Base64 string, which resolves any conflict with unicode. Also, knowing where one transformation block begins and where one ends can add difficulty with a Unicode log.



    using System;

    using System.IO;

    using System.Security.Cryptography;

    [System.Security.Permissions.FileIOPermission(System.Security.Permissions.SecurityAction.Demand, ViewAndModify=@"C:\log.log")]

    class Encryptor

    {

    static void Main(string[] args)

    {

    if (args.Length != 3)

    Console.WriteLine("Usage: program.exe Encrypt|Decrypt InputText|LineNumber Password");

    else

    {

    switch(args[0])

    {

    case "Encrypt":

    Console.WriteLine("Encrypt");

    Console.WriteLine("\tInputText: {0}", args[1]);

    Console.WriteLine("\tPassword: {0}\n", args[2]);

    Console.WriteLine("Input as Base64String:\n\t{0}", ES(args[1], args[2]));

    break;

    case "Decrypt":

    try

    {

    Console.WriteLine("Decrypt");

    Console.WriteLine("\tLine Number: {0}", args[1]);

    Console.WriteLine("\tPassword: {0}\n", args[2]);

    Console.WriteLine("Result:\n\t{0}", DS(Convert.ToInt32(args[1]), args[2]));

    break;}

    catch (FormatException)

    {

    Console.WriteLine("Invalid Line Number");

    break;}

    default:

    Console.WriteLine("Usage: program.exe Encrypt|Decrypt InputText|LineNumber Password");

    break;

    }

    }

    }

    public static string ES(string InputText, string Password)

    {

    RijndaelManaged RijndaelCipher = new RijndaelManaged();

    byte[] PlainText = System.Text.Encoding.ASCII.GetBytes(InputText);

    int PlainTextLength = System.Text.Encoding.ASCII.GetBytes(InputText).Length;

    byte[] Salt = System.Text.Encoding.ASCII.GetBytes(Password.Length.ToString());

    PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);

    ICryptoTransform ict = RijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));

    using(StreamWriter sw = new StreamWriter(@"C:\log.log", true, System.Text.Encoding.ASCII))

    {

    try

    {

    string enc = Convert.ToBase64String(ict.TransformFinalBlock(PlainText,0,PlainTextLength));

    sw.WriteLine(enc);

    return enc;

    }

    finally

    {

    ict.Dispose();

    }

    }

    }

    public static string DS(int LineNumber, string Password)

    {

    if(!File.Exists(@"C:\log.log"))

    File.Create(@"C:\log.log").Close();

    RijndaelManaged RijndaelCipher = new RijndaelManaged();

    byte[] Salt = System.Text.Encoding.ASCII.GetBytes(Password.Length.ToString());

    PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);

    ICryptoTransform ict = RijndaelCipher.CreateDecryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));

    using(StreamReader sw = new StreamReader(@"C:\log.log", System.Text.Encoding.ASCII))

    {

    try

    {

    System.Collections.Specialized.StringCollection sc = new System.Collections.Specialized.StringCollection();

    while(sw.Peek() >= 0)

    sc.Add(sw.ReadLine());

    if(LineNumber > sc.Count-1)

    Console.WriteLine("Error: {0} extends past the number of lines.", LineNumber);

    byte[] enc = Convert.FromBase64String(sc[LineNumber]);

    return System.Text.Encoding.ASCII.GetString(ict.TransformFinalBlock(enc,0,enc.Length));

    }

    finally

    {

    ict.Dispose();

    }

    }

    }

    }

     



    If unicode is an absolute must, then using a BinaryFormatter to serialize a collection would be the best approach for zero errors.



  • SSISy Boy

    Thanks VCS....Ive been toying with this:
    original URL:
    http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/de94e259634b2b3a/10bc73ef41064d06 lnk=st&q=Problem+appending+to+an+encrypted+file++c%23&rnum=1&hl=en#10bc73ef41064d06

    Im very close....it saves a those 8 bytes as small ugly blocks....or an 8 char space tho...

    using System;

    using System.IO;

    using System.Security;

    using Encrypted;

    using System.Security.Cryptography;

    using System.Text;

     

    namespace EncryptAppend

    {

    public class Crypto

    {

    private const string Key = "1234abcd";

    private static string LogFilePath;

    public static void UpdateLog(string Msg)

    {

    LogFilePath = "C:\\Log.log";

    DESCryptoServiceProvider DES = new DESCryptoServiceProvider();

    DES.Key = ASCIIEncoding.ASCII.GetBytes(Key);

    DES.IV = ASCIIEncoding.ASCII.GetBytes(Key);

    DES.Padding = PaddingMode.None;

    //if the file exists, use last 8 btyes as the IV

    if (System.IO.File.Exists(LogFilePath))

    {

    using (FileStream LogFile = new FileStream(LogFilePath, FileMode.Open))

    {

    LogFile.Position = LogFile.Length - 8;

    byte[] b = new byteMusic;

    LogFile.Read(b, 0, 8);

    DES.IV = b;

    }

    }

    using (FileStream LogFile = new

    FileStream(LogFilePath, FileMode.Append, FileAccess.Write))

    {

    using (ICryptoTransform desencrypt = DES.CreateEncryptor())

    {

    CryptoStream cryptostream = new

    CryptoStream(LogFile, desencrypt, CryptoStreamMode.Write);

    if (Msg.Length % (DES.BlockSize / 8) != 0)

    {

    Msg += new string(' ', (DES.BlockSize / 8) - Msg.Length % (DES.BlockSize /

    8));

    }

    byte[] bytearrayinput = new byte[Msg.Length];

    bytearrayinput = ASCIIEncoding.ASCII.GetBytes(Msg);

    cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);

    cryptostream.Close();

    }

    LogFile.Close();

    }

    }

    public static string ViewLog()

    {

    LogFilePath = "C:\\Log.log";

    DESCryptoServiceProvider DES = new DESCryptoServiceProvider();

    DES.Key = ASCIIEncoding.ASCII.GetBytes(Key);

    DES.IV = ASCIIEncoding.ASCII.GetBytes(Key);

    DES.Padding = PaddingMode.None;

    //read the encrypted file back.

    using (FileStream LogFile = new

    FileStream(LogFilePath, FileMode.Open, FileAccess.Read))

    {

    ICryptoTransform desdecrypt = DES.CreateDecryptor();

    CryptoStream cryptostreamDecr = new

    CryptoStream(LogFile, desdecrypt, CryptoStreamMode.Read);

    return (new StreamReader(cryptostreamDecr).ReadToEnd());

    }

    }

     

    //static void Main()

    //{

    // UpdateKL("\nThis is Message One Harry.");

    // UpdateKL("\nThis is Message Two. Sally");

    // UpdateKL("\nThis is Message Three Mary.");

    // //string s = ViewLog(Key);

    // //Console.Write(s);

    // Console.WriteLine("Press Enter to continue...");

    // //Console.ReadLine();

    //}

    }

    }





  • Encrypting (Appended) text file