c# - 正确的 C# Rijndael IV 用法/存储

标签 c# arrays rijndael initialization-vector

下午,

所以我对所有这些加密方法和用法都很陌生。我刚刚开始构建加密实现。现在我的加密和解密方法似乎工作正常。直到我读到我在 RijndaelManaged 类中使用硬编码 IV 时失败得很惨。

我到处都在读到,让每个加密文件的 IV 在“加密时间”唯一生成并保存在文件的开头/开头会更好(也更安全),因为其余的加密字节会在之后直接保存这。 (如果我理解正确的话)

我一直很难弄清楚我的问题,因为每次我加密文件时,我都会将 IV 写入前 16 个字节(正如类(class)、MSDN、Google 和该论坛上的一些人所建议的那样)文件的一部分,然后直接将其余的加密字节写入文件流。 (IV 以明文形式保存..或者未加密的字节 < 这也可以吗?)

我的问题是,当我尝试使用完全相同的 key 解密文件时失败了:在我开始读取文件 block 进行解密(缓冲)之前,我尝试读取文件的前 16 个字节以获得明文 IV 和在 RijndaelManaged 类实例中使用它。

这似乎失败了。我检查了一下,我想我可能在某个地方犯了一些小学生错误:因为一旦我想解密它,我似乎无法从加密文件中读取相同的 16 个字节。

这是我用来在加密之前进行文件处理的代码(不是加密本身)


using (RijndaelManaged RM = new RijndaelManaged())
using (FileStream StreamIN = new FileStream(FileIN, FileMode.Open, FileAccess.Read))
using (FileStream StreamOUT = new FileStream(FileOUT, FileMode.Append, FileAccess.Write))
{
    //Setup Variable ChunkSize and The Total bytes Read into the streams
    int ChunkSize = 1024 * 1024 * 32; 

    RM.GenerateIV();

    foreach (var item in RM.IV)
    {
        Console.Write("[ " + item + "] ");
    }

    StreamOUT.Seek(0, SeekOrigin.Begin);
    StreamOUT.Write(RM.IV, 0, RM.IV.Length);
    StreamOUT.Seek(RM.IV.Length, SeekOrigin.Begin);

    int TotalBytesRead = 0;                       

    //File Buffer Implementation
    for (long i = 0; i < StreamIN.Length; i += ChunkSize)
    {
        //ChunkData byte array determined by ChunkSize
        byte[] ChunkData = new byte[ChunkSize];
        //Current Bytes Read from the IN Stream
        int BytesRead = 0;
        while ((BytesRead = StreamIN.Read(ChunkData, 0, ChunkSize)) > 0)
        {
            //Call Encryption from local Class

            Console.WriteLine("Bytes Read: {0}", TotalBytesRead += BytesRead);

            ChunkData = Crypt.Encrypt(ChunkData, KeyBytes, RM.IV);

            //Write byte array to File
            StreamOUT.Write(ChunkData, 0, BytesRead);
        }
    }
}

这是我在解密之前处理文件的代码(不是解密本身)

using (RijndaelManaged RM = new RijndaelManaged())
using (FileStream StreamIN = new FileStream(FileIN, FileMode.Open, FileAccess.Read))
using (FileStream StreamOUT = new FileStream(FileOUT, FileMode.Append, FileAccess.Write))
{
    //Setup Variable ChunkSize and The Total bytes Read into the streams
    int ChunkSize = 1024 * 1024 * 32; 


    StreamIN.Seek(0, SeekOrigin.Begin);
    int Read = StreamIN.Read(RM.IV, 0, 16);
    StreamIN.Seek(RM.IV.Length, SeekOrigin.Begin);

    int TotalBytesRead = 0;

    foreach (var item in RM.IV)
    {
        Console.Write("[ " + item + "] ");
    }

    //File Buffer Implementation
    for (long i = 0; i < StreamIN.Length; i += ChunkSize)
    {
        //ChunkData byte array determined by ChunkSize
        byte[] ChunkData = new byte[ChunkSize];
        //Current Bytes Read from the IN Stream
        int BytesRead = 0;

        while ((BytesRead = StreamIN.Read(ChunkData, 0, ChunkSize)) > 0)
        {

            Console.WriteLine("Bytes Read: {0}", TotalBytesRead += BytesRead);                                

            //Call Decryption from local Class
            ChunkData = Crypt.Decrypt(ChunkData, KeyBytes, RM.IV);

            //Write byte Array to file
            StreamOUT.Write(ChunkData, 0, BytesRead);
        }
    }
}

我想这就是全部?此外,到目前为止,“控制台”和其他无用的调用只是为了帮助我检查和找出问题。 我正在使用 Visual Studios 2010,并尝试实现 RijndaelManaged 类。

加密/解密方法通过我的 key 和 IV 传递给 FileChunks(字节数组),这些方法返回一个保存到流中的字节数组(加密)。

我希望我的问题很清楚?如果不是我会尝试更好地解释, 我到处阅读以寻求有关此特定问题的帮助,但此处发布的大多数其他问题都超出了我的范围。

我真的很感激任何帮助,我确定我在某个地方犯了 clown 错误..

谢谢!!

最佳答案

根据长期Framework guidelines ,看起来 SymmetricAlgorithm.IV 已被编写为不返回内部数组。这意味着它会返回给您一个副本,因此对其进行的后续更改不会反射(reflect)在 RijndaelManaged 实例中。

// Effectively reading the persisted value into a temporary array
// and throwing away the temporary.
int Read = StreamIN.Read(RM.IV, 0, 16);

为了使更改保持不变并将 IV 设置为持久值,您需要实际显式设置 IV 属性,而不是仅仅修改它之前返回的值。

byte[] persistedIv = new byte[16];
StreamIN.Read(persistedIv, 0, persistedIv.Length);
RM.IV = persistedIv;

关于c# - 正确的 C# Rijndael IV 用法/存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12998848/

相关文章:

c# - StreamSocket、DataWriter.StoreAsync()、DataReader.LoadAsync() -- 异步问题

c# - 我想在整数数组的连续子集中找到公共(public)数字的最大频率

c# - 使用node.js解密使用c#加密的数据

c# - LINQ 查询到 Group 并获得 Sum

c# - 字典初始化器具有不同的行为,并在与数组初始化器组合使用时引发运行时异常

javascript - 使用 Javascript 重复数组中的值的函数

javascript - 如何在 React JS 中启用/禁用数组中的元素?

arrays - SSRS Reporting Services - 字符串中的粗体字

NodeJS 中的 PHP mcrypt_decrypt

python - rijndael:在 C 和 Python 中加密/解密相同的数据