-->

如何encrpyt /块中的数据进行解密?(How to encrpyt / decrypt dat

2019-09-28 10:45发布

我是很新的C#和加密,请宽容我。 我想节省一些二进制数据(“对象” - 其实大多只有对象的部分,因此,我不能/不会使用序列,和的BinaryWriter相似),我想它在内存中进行加密,然后使用的FileStream写。 起初我想用某种异或的,但我不知道它是那么容易打破,现在我改变了代码,使用AES。

事情是,我会有一些比较大的文件,而且经常我只需要改变或读取像32个字节的数据。 因此,我必须能够仅加密一个数据块的并且还能够对数据进行解密的唯一所需块的。 现在我来到了仅与下面的解决方案。

当通过所有的数据和循环内保存的数据我环路加密数据块,并将其写入文件。 一边读书,我有循环读取数据和环路我必须声明解密块里面,我觉得这非常低效的。

下面是加密和保存的代码:

        //setup file stream for saving data
        FileStream fStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read, 1024, false);

        //setup encryption (AES)
        SymmetricAlgorithm aes = Aes.Create();
        byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9, 50 };
        byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
        aes.Padding = PaddingMode.None;
        ICryptoTransform encryptor = aes.CreateEncryptor(key, iv);

        foreach(....)
        {
           //data manipulation

           //encryption
           MemoryStream m = new MemoryStream();
           using (Stream c = new CryptoStream(m, encryptor, CryptoStreamMode.Write))
              c.Write(data, 0, data.Length);
           byte[] original = new byte[32];
           original = m.ToArray();
           fStream.Write(original, 0, original.Length);
        }

密钥和IV是硬编码只是为了能够更容易调试和解决问题,一旦这将工作我会改的方向键和IV产生。

下面是阅读与解密代码:fstream的的FileStream =新的FileStream(文件名,FileMode.Open,FileAccess.Read,FileShare.Read,4096,FALSE);

            //setup encryption (AES)
            SymmetricAlgorithm aes = Aes.Create();
            byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9, 50 };
            byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
            aes.Padding = PaddingMode.None;

            //reading
            while (numBytesToRead > 0)
            {
                byte[] original = new byte[32];
                byte[] data = new byte[32];
                int len = fStream.Read(original, 0, 32);

                //error checking ...

               //decryption
                ICryptoTransform decryptor = aes.CreateDecryptor(key, iv);  //this is a slow operation
                MemoryStream m = new MemoryStream();
                using (Stream c = new CryptoStream(m, decryptor, CryptoStreamMode.Write))
                    c.Write(original, 0, original.Length);
                data = m.ToArray();

                //data manipulation ...
            }

那么事情是,我觉得非常低效的创建循环中的解密。 会有相当多的数据。 如果我在进入循环然后我不能正确地解密之前创建它,必须改变加密(声明加密流和循环之前内存流),但是然后我不能加密/解密只有期望的数据的块。 也没有很多的文件,这将只需要随机读/写。 例如,在一些文件,我会想从某个位置,直到文件的末尾,它可以是相当多的阅读。

请问你对此有何看法? 有没有更好的方式来实现这一目标? 也许不同的加密算法(在我想用某种异或的,但我发现它是非常容易“破解”开头)?

PS我想在内存中加密和我必须使用查找流。

Answer 1:

如果你想完全随机存取,欧洲央行是去(因为途中刚才的答复建议)。 你不会需要重新创建每个块加密流,因为它不使用IV和加密块不置换流(不像在密码文本取决于前面的程序段或块的位置大多数其他模式流)。 维基百科有一个很好的例子与这种模式的问题之一(该ciphertux图片)。

如果你的文件逻辑上由较大的块(如数据库记录或虚拟磁盘的磁盘扇区)的,你应该考虑他们作为加密单位。 在CBC模式中,你将(因此使用了一个附加的32个字节每块的存储设备)生成每个块一个新的随机IV每次写它,它与块存储时间,并且你将需要如果即使重写整个块单字节改变,但安全性会好很多。



Answer 2:

您可以使用ECB加密模式( CipherMode.ECB )。 其他加密模式反馈的密码和/或纯文本到文本的下一个块进行加密/解密。 这提供了更大的安全性,因为repeted部件以不同的方式进行加密。 然而,它需要完整的流被解密。

随着电子密码本(ECB)模式,每块单独加密,这样就可以实现在密码块边界随机访问。 然而,欧洲央行推出的漏洞,尤其是在纯文本是重复的。 看这里



Answer 3:

我只是给一个有关使用GCM,而不是欧洲央行的一角。 欧洲央行是因为你可能不知道一个非常安全的方式来做到这一点,我目前使用实施充气城堡API(检查这个线程:原型https://stackoverflow.com/a/10366194/637783 )。



Answer 4:

如果你想通过块解密块,你必须保持最后的8个字节,并把它作为IV为下一个块

while ((count = fileRead.Read(read, 0, 16)) > 0)
                {
                    if (transed > 0)
                        aes.IV = read;
                    transed += count;
                    ...
                }


文章来源: How to encrpyt / decrypt data in chunks?