如何加密/解密数据块? [英] How to encrpyt / decrypt data in chunks?

查看:88
本文介绍了如何加密/解密数据块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对C#和加密技术还很陌生,所以请耐心等待.我想保存一些二进制数据(对象"-实际上大部分只是对象的一部分,因此,我不能/不使用序列化,BinaryWriter等),并且想在内存中对其进行加密,然后使用FileStream进行写入.起初,我想使用某种Xor,但我不知道它是如此容易破解,现在我更改了代码以使用Aes.

I'm quite new to C# and encryption so please have patience with me. I want to save some binary data ("objects" - in fact mostly only parts of objects, thus I can't / don't use serialization, BinaryWriter and similar) and I want to encrypt it in memory and then write it using FileStream. At first I wanted to use some sort of Xor but I didn't know that it is so easy to break, now I changed code to use Aes.

问题是,我将拥有一些相对较大的文件,并且经常只需要更改或读取32个字节的数据即可.因此,我必须只能加密一个数据块,也只能解密所需的数据块.目前,我只想出以下解决方案.

The thing is that I will have some relatively large files and quite often I will only need to change or read like 32 bytes of data. Thus I must be capable of encrypting only one chunk of data and also capable of decrypting only desired chunks of data. For now I came up only with the following solution.

保存数据时,我循环浏览所有数据,并在循环内部加密一部分数据并将其写入文件.在读取时,我有一个循环,它读取大块数据,并且在循环中我必须声明解密器,这发现效率很低.

When saving data I loop through all the data and inside the loop encrypt a chunk of data and write it to a file. While reading, I have loop which reads chunks of data and inside the loop I have to declare the decryptor, which I find very inefficient.

这是加密和加密的代码正在保存:

Here's the code for encryption & saving:

        //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的生成方式.

The key and iv is hardcoded just to enable easier debugging and solving problems, once this will work I'll change the way key and iv are generated.

这是阅读和阅读的代码解密:FileStream fStream = new FileStream(fileName,FileMode.Open,FileAccess.Read,FileShare.Read,4096,false);

Here's the code for reading & decryption: FileStream fStream = new FileStream(fileName, 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 ...
            }

好吧,我发现在循环中创建解密器的效率很低.将会有很多数据.如果我在进入循环之前创建了它,那么我将无法正确解密,而不得不更改加密(在循环之前声明加密流和内存流),但是那样我就无法仅加密/解密所需的数据块.另外,文件很少,只需要随机读取/写入即可.例如,在某些文件中,我要从某个位置读取直到文件结尾,这可能很多.

Well the thing is that I find it very inefficient to create a decryptor in a loop. There will be quite a lot of data. If I create it before entering the loop then I can't decrypt properly and have to change encryption (declare encryption stream and memory stream before loop), but then I can't encrypt / decrypt only desired chunk of data. Also there aren't many files which would only require random reading / writing. For instance at some files I'll want to read from a certain position till the end of file, which can be quite a lot.

您对此有何看法?有没有更好的方法来实现这一目标?也许是不同的加密算法(一开始我想使用某种xor,但我发现破解"非常容易)?

What's your view on this? Is there a better way to achieve this? Maybe different encryption algorithm (in the beginning I wanted to use some sort of xor but I found out it is very easy to "crack") ?

p.s.我想在内存中加密,必须使用可搜索的流.

p.s. I want to encrypt in memory and I must use seekable streams.

推荐答案

如果您希望完全随机访问,则可以使用ECB(如精美的插图(密码图片)此模式的问题之一.

If you want full random access, ECB is the way to go (as the earlier answer recommends). You would not need to recreate the encryption stream for each block, because it doesn't use an IV and encrypting a block doesn't permute the stream (unlike most other modes where the cryptotext depends on previous blocks or the position of the block in the stream). Wikipedia has a nice illustration (the ciphertux picture) of one of the problems with this mode.

如果文件在逻辑上由较大的块(例如数据库记录或虚拟磁盘中的磁盘扇区)组成,则应考虑将它们加密为单位.在CBC模式下,您每次写入块时都会为每个块生成一个新的随机IV并将其与该块一起存储(因此,每个块将占用额外的32个字节的存储空间),并且即使更改单个字节,但安全性会更好.

If your file logically consists of larger chunks (such as database records or disk sectors in virtual disks), you should consider encrypting them as units. In CBC mode you would generate a new random IV for each chunk each time you write it and store it with the block (thus using up an additional 32 bytes of storage per chunk), and you would need to rewrite the entire chunk even if a single byte changes, but the security would be much better.

这篇关于如何加密/解密数据块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆