簡體   English   中英

正確的C#Rijndael IV使用/存儲

[英]Proper C# Rijndael IV Usage/Storage

下午,

因此,我對所有這些加密方法和用法都不陌生。 我剛剛開始構建加密實現。 現在,我的加密和解密方法似乎可以正常工作。直到我讀到我在RijndaelManaged類中使用Hardcoded IV慘敗。

我到處都讀到,最好在“加密時間”唯一地生成每個加密文件的IV,並保存在文件的開頭/開頭,這樣更好(更安全),其余的加密字節則在此之后直接保存。 (如果我理解正確)

我一直很難解決我的問題,因為每次我加密文件時,我都會將IV寫入文件的前16個字節(如該類,MSDN,Google和該論壇上的某些人士所建議)然后直接將其余的加密字節寫入文件流。 (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);
        }
    }
}

我認為就這些了嗎? 另外,“ Console”和其他無用的調用只是為了幫助我檢查並找出目前的問題。 我正在使用Visual Studios 2010,並嘗試實現RijndaelManaged類。

加密/解密方法與我的密鑰和IV一起傳遞給FileChunks(字節數組),這些方法返回一個字節數組(加密),該字節數組保存到流中。

我希望我的問題清楚嗎? 如果不是,我會盡力解釋得更好,我讀過很多文章,尋求有關此特定問題的幫助,但此處發布的大多數其他問題不在我的討論范圍之內。

我真的很感謝您的幫助,我確定我在某個地方犯了一個小丑錯誤。

謝謝!!

根據長期的Framework准則 ,看起來SymmetricAlgorithm.IV已編寫為不返回內部數組。 這意味着它將把副本退還給您,因此對它的后續更改不會反映在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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM