C# 逐行加密/解密文件?

C# 逐行加密/解密文件?,c#,encryption,rijndaelmanaged,character-encoding,encoding,C#,Encryption,Rijndaelmanaged,Character Encoding,Encoding,我对加密相当陌生,我正在尝试让一个逐行加密机工作;我需要能够在应用程序运行时将加密的行附加到文件中,而不是只对所有内容进行一次大规模的加密和保存。不过,我和它相处得很愉快。这是我的加密机,在我自己多次尝试失败后不知羞耻地被偷了: class Encryption { private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5

我对加密相当陌生,我正在尝试让一个逐行加密机工作;我需要能够在应用程序运行时将加密的行附加到文件中,而不是只对所有内容进行一次大规模的加密和保存。不过,我和它相处得很愉快。这是我的加密机,在我自己多次尝试失败后不知羞耻地被偷了:


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 私有void加密文件(字符串文件路径、字符串输出路径、字符串密码) { FileInfo FileInfo=新的FileInfo(filepath); 字符串文件名=fileInfo.Name; 字符串fullpath=outputPath+“\\”+文件名; BinaryWriter=新的BinaryWriter(File.OpenWrite(fullpath),Encoding.ASCII); ///我在这里尝试了两种方法: ///1.理想的方法:逐行加密-我假设我能够生成 ///多个数据块,稍后再解密。这不起作用 //string[]lines=File.ReadAllLines(文件路径); ///2.只需通读整件事,然后一下子加密并写入即可。 字符串行=File.ReadAllText(文件路径); //foreach(行中的字符串行) { byte[]bytes=Encoding.ASCII.GetBytes(行); 字节[]编码=加密。加密(字节,密码); writer.Write(编码); writer.Flush(); } writer.Close(); } 私有无效解密文件(字符串文件路径、字符串输出路径、字符串密码) { FileInfo FileInfo=新的FileInfo(filepath); 字符串文件名=fileInfo.Name; 字符串fullpath=outputPath+“\\”+文件名; StreamWriter writer=新的StreamWriter(完整路径,false,Encoding.UTF8); byte[]bytes=File.ReadAllBytes(文件路径); ///这是目前正在进行解密的方法;只是 ///抓取所有数据,一下子解密。 byte[]decrypted=加密。解密(字节,密码); 字符串s=Encoding.ASCII.GetString(已解密); 作者:写; writer.Flush(); ///我尝试了很多方法来逐行解密, ///这些都不起作用。这会因为填充问题而崩溃 ///无效的。 /* int指数=0; 整数计数=32; while(索引)
我不完全确定我应该再做什么。我一直在四处闲逛,在网上浏览一些东西和例子,但它们似乎都是如何加密整个文件或只是加密一段数据,除了立即再次解密之外什么也不做。我应该如何处理逐行写入?

而不是pr为您编程,我将给您一个您可以实施的方案

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

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

  • 加密文本应以行形式显示,这意味着字节需要从二进制转换为字符(使用)
  • 您希望使用单个密钥,同时保持安全
  • 您不需要密码文本的完整性保护或身份验证,只需要保密
现在的想法很简单:

  • 使用基于密码的密钥派生函数创建单个密钥
  • 打开文本文件进行阅读(使用正确的格式)
  • 读取一行并再次将该行转换为字节(例如,使用UTF-8)
  • 创建一个在下面创建字节数组的输出流
  • 创建一个随机IV并将其写入字节数组(IV始终是单个块大小)
  • 创建加密流并将其连接到同一输出流
  • 对编码行进行加密
  • base 64对加密的字节进行编码,并确保它保持在一行中
  • 将已编码、加密的行写入新的文本文件

  • 相反,请反向执行此过程,尽管IV应该在base64解码后从字节中检索,并且密钥当然应该使用加密过程中使用的相同方法进行计算。

    输出文件应该是什么样子?文本文件还是二进制流?您可能不想逐行读取。相反,您需要t将文件作为流抓取,然后使用加密流。对于那些对加密一无所知的人,IV是初始化向量。有时称为“nonce”或使用过一次的数字。