.NET中如何安全地存儲認證信息(C#)

.NET中如何安全地存儲認證信息(C#)

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()加密一小段數據:

// 需要被保護的數據。使用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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章