TODO: 本文由 赤石俊哉 翻譯整理,您能夠將本文自由地用於學習交流。如需用於其餘用途請徵得做者的贊成。
原文連接:How to securely save username/password (local)? - StackOverFlow算法
若是你只但願驗證輸入的用戶名和密碼是否匹配,可使用Rfc2898DerivedBytes
類(即PBKDF2
)。這比起使用諸如三次DES以及AES這樣的加密算法來講要更安全一些,由於從RFC2898DerivedBytes
產生的結果逆推出密碼原文是不可行的。你只能將密碼轉換成PBKDF2
的結果。
你能夠參考使用密碼的SHA1哈希值做爲密碼字符串推導加密祕鑰和向量的鹽,是否可行?,
這裏面有一個示例,也討論了在WinRT/Metro環境的.Net環境下C# Metro風格的密碼字符串加密解密。數組
若是你但願存儲密碼以便之後進行復用,你可使用Windows Data Protection API(DPAPI)
。
它是使用了操做系統生成而且保護的密鑰進行三次DES加密算法來加密解密信息的。
這就意味着你的應用程序能夠省去一個大麻煩,那就是它不須要去關心密鑰如何去生成以及保護。安全
在C#
中,使用System.Security.Cryptography.ProtectedData
類。
舉個例子,使用ProtectedData.Protect()
加密一小段數據:ide
// 須要被保護的數據。使用Encoding.UTF8.GetBytes()將一個字符串轉換成byte數組。 byte[] plaintext; // 生成一個附加的熵(用於向量的初始化) byte[] entropy = new byte[20]; using(RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()){ rng.GetBytes(entropy); } byte[] ciphertext = ProtectedData.Protect(plaintext, entropy, DataProtectionScope.CurrentUser);
安全地存儲熵值(entropy
)和加密後文本(ciphertext
),好比存儲在一個只有當前用戶具備讀寫權限的文件或者註冊表項內。
在程序中,須要訪問原始數據的時候,只須要使用ProtectedData.Unprotect()
:學習
byte[] plaintext = ProtectedData.Unprotect(ciphertext, entropy, DataProtectionScope.CurrentUser);
還有一些其餘要注意的安全考慮,好比,避免直接將像密碼這類的隱私信息存儲爲一個字符串(string
),這樣作的話在內存中是不可被通知的,因此其餘人要是查看程序的內存或者Dump內存的時候,就會看到密碼。
使用SecureString
或者一個byte數組來代替。在不須要使用密碼的時候,儘快釋放掉他們,或者是所有填寫0。加密