我正在研究一個簡單的實用程序來加密文件作爲學習體驗。 一切似乎工作正常,但我想知道如果我已安全地設置密鑰/ IV /鹽數據。Rijndael加密功能 - 密鑰/ IV /鹽設置
我注意到,當涉及到密碼術時,大多數人似乎設想到一個工作環境,加載了一個惡意軟件,該惡意軟件由遠程嚮導遠程準備通過正在運行的應用程序/頁面文件的內存來獲取這些安全文件。
讓我們假裝你在一臺乾淨的機器上,然後加密一些文件並關閉計算機。 我想知道的是,某人是否可以拿走你的硬盤,並使用我提出的代碼檢索文件的內容。
我最關心的攻擊矢量是確保頁面文件/文件緩存不可訪問。 我也想確保使用的Key/IV系統不會使基於彩虹表/散列的攻擊變得可行。
輸入密碼:使用設置爲true的passwordchar值的文本框中輸入
的密碼。
只要在加密後正確刪除字符串,我並不關心字符串在內存中。我讀到使用SecureString在這一點上是毫無意義的,因爲如果您的計算機上已經存在惡意軟件,那麼您可以輕鬆地在其上放置一個鍵盤記錄器,這會導致其他一切無用。
private static string salt = "02341235XadfaDADFexA8932F7Dz3J3X";
我使用硬編碼的32個字符的字符串給密碼加鹽。 (上面的字符串只是一個例子)
爲了解決這個問題,它需要有人用十六進制編輯器反編譯/查看.exe文件本身(我知道的東西很容易做到,但是額外的步驟)。
我曾考慮過這種鹽是可編輯的,但我不知道如何安全地存儲它。我認爲加密你的鹽有點荒謬,因爲那樣你就會遇到同樣的問題,所以把它作爲一個硬編碼的字符串放在exe文件中看起來對我來說最有意義。
這種方式的工作方式是,如果你決定讓你的密碼「密碼」,它實際上保存爲「thepasswordfaDADFexA8932F7Dz3J3X」。
這裏的主要關鍵是你總是有一個32個字符的密碼,而不管你輸入什麼。
密鑰和IV:
密鑰和IV也鹽醃如下。 這是我希望得到一些意見,因爲說實話,我不是很確定它在做什麼:
UnicodeEncoding UE = new UnicodeEncoding();
byte[] keysalt = UE.GetBytes("Xjafe231x42X423XadXCadfkhjeAdS"); //Another string of random characters hard coded in the exe
byte[] IVSodium = UE.GetBytes("83Xkda7l78Dkx85KdJazppoqq6SaxDs"); //Another string of random characters hard coded in the exe
byte[] key = new Rfc2898DeriveBytes(password, keysalt).GetBytes(32); //Derive the key using the password and salt
byte[] IV = new Rfc2898DeriveBytes(password, IVSodium).GetBytes(16); //Derive the IV using the password and salt
我主要在這裏擔心的是,IV基於關鍵。再次,我不確定這是否會導致任何問題,我希望你們可以讓我知道是否有問題,它們是什麼。
此外,這是另一種情況下,硬編碼鹽是一種不好的做法?這應該存儲在加密文件中,如果是這樣,它是否真的使它更安全?我應該讓這個可編輯嗎?
的加密流是使用使用關鍵字的設置:
using (FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create))
{
using (RijndaelManaged RMCrypto = new RijndaelManaged())
{
using (CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, IV), CryptoStreamMode.Write))
{
using (FileStream fsIn = new FileStream(inputFile, FileMode.Open))
{
byte[] buffer = new byte[4096]; //4096 is kind of arbitrary - better idea?
int data;
long bytesRead = 0;
while((data = fsIn.Read(buffer, 0, buffer.Length)) > 0)
{
bytesRead += data;
/////////////////////////////////////////
// Handle Aborts and Update Progress Bar
/////////////////////////////////////////
if (!caller.isClosing)
caller.Invoke((MethodInvoker)delegate {
caller.fileProgressBar.Value = ((int)(((double)bytesRead/totalBytes) * 100));
});
else
return false; //Encryption Aborted
/////////////////////////////////////////
cs.Write(buffer, 0, data);
fsIn.Close();
cs.Close();
fsCrypt.Close();
return true;
}
}
}
}
}
感謝您的時間和請讓我知道,如果有設置鍵/ IV /鹽更好的辦法。 我認爲,只要沒有包含類似字符的IV和Key的數學問題,它就很可能足夠安全。如果是這樣,我是否也應該使用硬編碼的IV?這似乎很奇怪。
請注意,我沒有保存密碼或任何類似的散列。密碼不保存在任何地方。它只是用來生成密鑰和IV。
謝謝你的時間。
編輯:下面是對未來的任何人推薦的更改。
請注意,這不是用胡椒 - 只是一個隨機的鹽,雖然這將是很容易的添加
byte[] salt = new byte[32]; //Create a 32 byte salt
rand.NextBytes(salt); //Fill it with random values (use RandomNumberGenerator rand = new RNGCryptoServiceProvider(); to be safe
byte[] IV = new byte[16]; //Create a 16 byte IV
rand.NextBytes(IV); //Fill it with random numbers
byte[] key = new Rfc2898DeriveBytes(password, salt).GetBytes(32); //Derive our Key by mixing our password with the salt
using (FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create))
{
using (RijndaelManaged RMCrypto = new RijndaelManaged())
{
using (CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, IV), CryptoStreamMode.Write))
{
using (FileStream fsIn = new FileStream(inputFile, FileMode.Open))
{
fsCrypt.Write(salt, 0, salt.Length); //Write our salt to the file
fsCrypt.Write(IV, 0, IV.Length); //Write our IV to the file
fsIn.CopyTo(cs); //Encrypt and Write
}
}
}
}
不要使用固定鹽,鹽的一點是如果密碼重用,你不能說它被重用。鹽不需要保密,只需將其附加到正在加密的文件的前面。 –
好的,那麼直接把鹽寫入被加密文件的開始處?此外,鹽在這裏真的有必要嗎?我沒有散列任何東西。沒有存儲的密碼。我想確保密碼可以是任意長度,並且仍然可以使用算法,所以我知道它需要一定數量的字符長度。缺少硬編碼或將隨機字符附加到文件的開頭(基本上是同一個東西,不是?)會影響任何內容嗎?基本上,我可能會錯誤地將它稱爲鹽來解釋它。 – user1274820