人人做人人澡人人爽欧美,国产主播一区二区,久久久精品五月天,羞羞视频在线观看免费

當前位置:蘿卜系統下載站 > 技術開發教程 > 詳細頁面

詳細說明對密碼執行散列與 salt 運算辦法

詳細說明對密碼執行散列與 salt 運算辦法

更新時間:2022-08-30 文章作者:未知 信息來源:網絡 閱讀次數:

  大家對密碼執行散列和Salt運算一定不陌生。兩個Visual Studio企業版示例都是用的這個方法來加密這個方法的。結合示例代碼,我總結了一個包含對密碼進行加密,比較等靜態方法的類。
  使用說明:先用HashAndSalt方法對密碼進行加密,然后存儲到數據庫中。 在用戶登錄時用ComparePasswords方法在對用戶輸入的密碼和用戶注冊時存儲在數據庫中的密碼進行比較,判斷用戶輸入的密碼是否正確。

 

Credentials.cs

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
 
namespace BookStore.Common
{
       /// <summary>
       /// Credentials 的摘要說明。
       /// 原理:
       /// 對密碼執行散列運算
       /// 若要避免以明文形式存儲密碼,一種常見的安全做法是對密碼執行散列運算。如以下代碼所示,使用 System.Security.Cryptography 命名空間(它實現 160 位 SHA-1 標準)對密碼進行散列運算。有關更多信息,請參見 SHA1 成員。
       /// 對散列執行 Salt 運算
       /// 雖然對密碼執行散列運算的一個好的開端,但若要增加免受潛在攻擊的安全性,則可以對密碼散列執行 Salt 運算。Salt 就是在已執行散列運算的密碼中插入的一個隨機數字。這一策略有助于阻止潛在的攻擊者利用預先計算的字典攻擊。字典攻擊是攻擊者使用密鑰的所有可能組合來破解密碼的攻擊。當您使用 Salt 值使散列運算進一步隨機化后,攻擊者將需要為每個 Salt 值創建一個字典,這將使攻擊變得非常復雜且成本極高。
       /// Salt 值隨散列存儲在一起,并且未經過加密。所存儲的 Salt 值可以在隨后用于密碼驗證。
       /// </summary>
       public class Credentials
       {
              private static string key = "!48%0d-F=cj>,s&2";  //密鑰(增加密碼復雜度,好像比較多余)
              private const int saltLength = 4;                         //定義salt值的長度
 
              /// <summary>
              /// 對密碼進行Hash 和 Salt
              /// </summary>
              /// <param name="Password">用戶輸入的密碼</param>
              /// <returns></returns>
              public static byte[] HashAndSalt(string Password)
              {
                     return CreateDbPassword(HashPassword(Password));
              }
 
              /// <summary>
              /// 對用戶輸入的密碼加上密鑰key后進行SHA1散列
              /// </summary>
              /// <param name="Password">用戶輸入的密碼</param>
              /// <returns>返回 160 位 SHA-1 散列后的的byte[](160位對應20個字節)</returns>
              private static byte[] HashPassword( string Password )
              {
                     //創建SHA1的對象實例sha1
                     SHA1 sha1 = SHA1.Create();
                     //計算輸入數據的哈希值
                     return sha1.ComputeHash( Encoding.Unicode.GetBytes( Password + key ) );
              }
             
              /// <summary>
              /// 比較數據庫中的密碼和所輸入的密碼是否相同
              /// </summary>
              /// <param name="storedPassword">數據庫中的密碼</param>
              /// <param name="Password">用戶輸入的密碼</param>
              /// <returns>true:相等/false:不等</returns>
              public static bool ComparePasswords(byte[] storedPassword, string Password)
              {
                     //首先將用戶輸入的密碼進行Hash散列
                     byte[] hashedPassword = HashPassword(Password);
 
                     if (storedPassword == null || hashedPassword == null || hashedPassword.Length != storedPassword.Length - saltLength)
                     {
                            return false;
                     }
 
                     //獲取數據庫中的密碼的salt 值,數據庫中的密碼的后4個字節為salt 值
                     byte[] saltValue = new byte[saltLength];
                     int saltOffset = storedPassword.Length - saltLength;
                     for (int i = 0; i < saltLength; i++){
                            saltValue[i] = storedPassword[saltOffset + i];
                     }
                    
                     //用戶輸入的密碼用戶輸入的密碼加上salt 值,進行salt
                     byte[] saltedPassword = CreateSaltedPassword(saltValue, hashedPassword);
             
                     //比較數據庫中的密碼和經過salt的用戶輸入密碼是否相等
                     return CompareByteArray(storedPassword, saltedPassword);
              }
 
              /// <summary>
              /// 比較兩個ByteArray,看是否相等
              /// </summary>
              /// <param name="array1"></param>
              /// <param name="array2"></param>
              /// <returns>true:相等/false:不等</returns>
              private static bool CompareByteArray(byte[] array1, byte[] array2)
              {
                     if (array1.Length != array2.Length)
                     {
                            return false;
                     }
                     for (int i = 0; i < array1.Length; i++)
                     {
                            if (array1[i] != array2[i])
                            {
                                   return false;
                            }
                     }
                     return true;
              }
 
              /// <summary>
              /// 對要存儲的密碼進行salt運算
              /// </summary>
              /// <param name="unsaltedPassword">沒有進行過salt運算的hash散列密碼</param>
              /// <returns>經過salt的密碼(經過salt的密碼長度為:20+4=24,存儲密碼的字段為Binary(24))</returns>
              private static byte[] CreateDbPassword(byte[] unsaltedPassword)
              {
                     //獲得 salt 值
                     byte[] saltValue = new byte[saltLength];
                     RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
                     rng.GetBytes(saltValue);
                    
                     return CreateSaltedPassword(saltValue, unsaltedPassword);
              }
             
              /// <summary>
              /// 創建一個經過salt的密碼
              /// </summary>
              /// <param name="saltValue">salt 值</param>
              /// <param name="unsaltedPassword">沒有進行過salt運算的hash散列密碼</param>
              /// <returns>經過salt的密碼</returns>
              private static byte[] CreateSaltedPassword(byte[] saltValue, byte[] unsaltedPassword)
              {
                     //將salt值數組添加到hash散列數組后拼接成rawSalted數組中
                     byte[] rawSalted  = new byte[unsaltedPassword.Length + saltValue.Length];
                     unsaltedPassword.CopyTo(rawSalted,0);
                     saltValue.CopyTo(rawSalted,unsaltedPassword.Length);
                    
                     //將合并后的rawSalted數組再進行SHA1散列的到saltedPassword數組(長度為20字節)
                     SHA1 sha1 = SHA1.Create();
                     byte[] saltedPassword = sha1.ComputeHash(rawSalted);
 
                     //將salt值數組在添加到saltedPassword數組后拼接成dbPassword數組(長度為24字節)
                     byte[] dbPassword  = new byte[saltedPassword.Length + saltValue.Length];
                     saltedPassword.CopyTo(dbPassword,0);
                     saltValue.CopyTo(dbPassword,saltedPassword.Length);
 
                     return dbPassword;
              }
 
       }
}


溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

網站地圖xml | 網站地圖html
主站蜘蛛池模板: 紫金县| 四平市| 康乐县| 隆林| 大邑县| 蒲城县| 砀山县| 宣恩县| 新绛县| 拉萨市| 绿春县| 军事| 浠水县| 大理市| 乌海市| 崇信县| 高雄市| 上栗县| 东平县| 岳池县| 印江| 明水县| 乐昌市| 仪陇县| 虞城县| 永顺县| 宝鸡市| 乐都县| 枣强县| 阿拉善盟| 东海县| 奉新县| 昔阳县| 汉沽区| 泰州市| 西宁市| 全南县| 武安市| 海阳市| 曲阳县| 东辽县|