[英]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.