2

下午,

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

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

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

我的问题是,当我尝试使用完全相同的密钥解密文件时,它失败了:在我开始读取文件的块进行解密(缓冲)之前,我尝试读取文件的前 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 类。

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

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

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

Thank you!!

4

1 回答 1

1

As per long-standing Framework guidelines, it looks like SymmetricAlgorithm.IV has been written not to return an internal array. This means that it's handing you back a copy, so subsequent changes to it aren't reflected in the RijndaelManaged instance.

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

In order to make the change stick and set the IV to the persisted value, you need to actually set the IV property explicitly, rather than just modifying the value it returned previously.

byte[] persistedIv = new byte[16];
StreamIN.Read(persistedIv, 0, persistedIv.Length);
RM.IV = persistedIv;
于 2012-10-21T20:22:34.183 回答