逐行加密/解密文件?

时间:2012-10-21 16:55:29

标签: c# encryption rijndaelmanaged

我是加密的新手,我正在尝试使用逐行加密器工作;我需要能够在应用程序运行期间将加密的行附加到文件中,而不是仅仅进行一次大规模加密 - 一切和保存。虽然我有一个时间的野兽。这是我的加密器,在我自己尝试了几次失败后无耻地被盗:


class Encryption
    {
        private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c };

        public static byte[] Encrypt(byte[] plain, string password)
        {
            MemoryStream memoryStream;
            CryptoStream cryptoStream;
            Rijndael rijndael = Rijndael.Create();
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, SALT);
            rijndael.Key = pdb.GetBytes(32);
            rijndael.IV = pdb.GetBytes(16);
            memoryStream = new MemoryStream();
            cryptoStream = new CryptoStream(memoryStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write);
            cryptoStream.Write(plain, 0, plain.Length);
            cryptoStream.FlushFinalBlock();
            cryptoStream.Close();
            return memoryStream.ToArray();
        }

        public static byte[] Decrypt(byte[] cipher, string password)
        {
            MemoryStream memoryStream;
            CryptoStream cryptoStream;
            Rijndael rijndael = Rijndael.Create();
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, SALT);
            rijndael.Key = pdb.GetBytes(32);
            rijndael.IV = pdb.GetBytes(16);
            memoryStream = new MemoryStream();
            cryptoStream = new CryptoStream(memoryStream, rijndael.CreateDecryptor(), CryptoStreamMode.Write);
            cryptoStream.Write(cipher, 0, cipher.Length);
            cryptoStream.FlushFinalBlock();
            cryptoStream.Close();
            return memoryStream.ToArray();
        }
    }

这是一个虚拟函数,显示我是如何尝试的:


       private void EncryptFile(string filepath, string outputPath, string password)
        {
            FileInfo fileInfo = new FileInfo(filepath);
            string filename = fileInfo.Name;

            string fullpath = outputPath + "\\" + filename;

            BinaryWriter writer = new BinaryWriter(File.OpenWrite(fullpath), Encoding.ASCII);

            /// Two methods that I've attempted here:
            /// 1.  The desired method: encrypt line by line - I assumed I'd be able to generate
            ///     multiple blocks of data and decrypt them later.  This isn't working

            //string[] lines = File.ReadAllLines(filepath);

            /// 2.  Just read the whole thing and encrypt and write it in one swoop.

            string line = File.ReadAllText(filepath);

            //foreach(string line in lines)
            {
                byte[] bytes = Encoding.ASCII.GetBytes(line);
                byte[] encoded = Encryption.Encrypt(bytes, password);

                writer.Write(encoded);
                writer.Flush();
            }

            writer.Close();
        }



        private void DecryptFile(string filepath, string outputPath, string password)
        {
            FileInfo fileInfo = new FileInfo(filepath);
            string filename = fileInfo.Name;
            string fullpath = outputPath + "\\" + filename;

            StreamWriter writer = new StreamWriter(fullpath, false, Encoding.UTF8);

            byte[] bytes = File.ReadAllBytes(filepath);

            ///  Here is the method that's working at the moment for decrypting; just
            ///  grab all the data and decrypt it on one swoop.

            byte[] decrypted = Encryption.Decrypt(bytes, password);

            string s = Encoding.ASCII.GetString(decrypted);

            writer.Write(s);
            writer.Flush();


            ///  I've tried a number of things here to decrypt line by line,
            ///  none of which work.  This crashes with an issue about the padding
            ///  being invalid.  

            /*
            int index = 0;
            int count = 32;

            while (index 

我不完全确定我应该做什么。我一直在四处闲逛,通过在线阅读示例,但它们似乎都是如何加密整个文件,或者只是加密一段数据而不对它做任何事情,除了立即再次解密。我应该如何处理逐行写作?

1 个答案:

答案 0 :(得分:4)

不是为你编程,而是给你一个你可以实现的方案。

如果你有每行加密,我认为你也希望能够在每行解密。注意,“线”对于计算机来说是相当不方便的术语。它只是一堆以某种行终结符结尾的字符。字符本身使用特定的进行编码。

此外,我将做出以下假设:

  • 加密文本应以行显示,这意味着需要将字节从二进制转换为字符(使用);
  • 您希望使用单个密钥,同时保持安全;
  • 您不需要完整性保护或密文验证,只需要保密。

现在这个想法很简单:

  1. 使用基于密码的密钥派生函数创建单个密钥;
  2. 打开文本文件进行阅读(使用正确的);
  3. 读取一行并再次将该行转换为字节(例如,使用UTF-8);
  4. 创建一个输出流,在下面创建一个字节数组;
  5. 创建一个随机IV并将其写入字节数组(IV始终是单个块大小);
  6. 创建加密流并将其连接到同一输出流;
  7. 加密编码行;
  8. base 64编码加密的字节,并确保它保持在一行;
  9. 将编码的加密行写入新的文本文件。
  10. 相反,反过来,虽然应该在base 64解码后从字节中检索IV,并且当然应该使用加密期间使用的相同方法计算密钥。