六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

詳細說明對密碼執(zhí)行散列與 salt 運算方法

[摘要]大家對密碼執(zhí)行散列和Salt運算一定不陌生。兩個Visual Studio企業(yè)版示例都是用的這個方法來加密這個方法的。結(jié)合示例代碼,我總結(jié)了一個包含對密碼進行加密,比較等靜態(tài)方法的類! ∈褂谜f明:先用HashAndSalt方法對密碼進行加密,然后存儲到數(shù)據(jù)庫中。 在用戶登錄時用ComparePa...

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

 

Credentials.cs

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
 
namespace BookStore.Common
{
       /// <summary>
       /// Credentials 的摘要說明。
       /// 原理:
       /// 對密碼執(zhí)行散列運算
       /// 若要避免以明文形式存儲密碼,一種常見的安全做法是對密碼執(zhí)行散列運算。如以下代碼所示,使用 System.Security.Cryptography 命名空間(它實現(xiàn) 160 位 SHA-1 標準)對密碼進行散列運算。有關(guān)更多信息,請參見 SHA1 成員。
       /// 對散列執(zhí)行 Salt 運算
       /// 雖然對密碼執(zhí)行散列運算的一個好的開端,但若要增加免受潛在攻擊的安全性,則可以對密碼散列執(zhí)行 Salt 運算。Salt 就是在已執(zhí)行散列運算的密碼中插入的一個隨機數(shù)字。這一策略有助于阻止?jié)撛诘墓粽呃妙A(yù)先計算的字典攻擊。字典攻擊是攻擊者使用密鑰的所有可能組合來破解密碼的攻擊。當您使用 Salt 值使散列運算進一步隨機化后,攻擊者將需要為每個 Salt 值創(chuàng)建一個字典,這將使攻擊變得非常復(fù)雜且成本極高。
       /// Salt 值隨散列存儲在一起,并且未經(jīng)過加密。所存儲的 Salt 值可以在隨后用于密碼驗證。
       /// </summary>
       public class Credentials
       {
              private static string key = "!48%0d-F=cj>,s&2";  //密鑰(增加密碼復(fù)雜度,好像比較多余)
              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位對應(yīng)20個字節(jié))</returns>
              private static byte[] HashPassword( string Password )
              {
                     //創(chuàng)建SHA1的對象實例sha1
                     SHA1 sha1 = SHA1.Create();
                     //計算輸入數(shù)據(jù)的哈希值
                     return sha1.ComputeHash( Encoding.Unicode.GetBytes( Password + key ) );
              }
             
              /// <summary>
              /// 比較數(shù)據(jù)庫中的密碼和所輸入的密碼是否相同
              /// </summary>
              /// <param name="storedPassword">數(shù)據(jù)庫中的密碼</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;
                     }
 
                     //獲取數(shù)據(jù)庫中的密碼的salt 值,數(shù)據(jù)庫中的密碼的后4個字節(jié)為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);
             
                     //比較數(shù)據(jù)庫中的密碼和經(jīng)過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>經(jīng)過salt的密碼(經(jīng)過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>
              /// 創(chuàng)建一個經(jīng)過salt的密碼
              /// </summary>
              /// <param name="saltValue">salt 值</param>
              /// <param name="unsaltedPassword">沒有進行過salt運算的hash散列密碼</param>
              /// <returns>經(jīng)過salt的密碼</returns>
              private static byte[] CreateSaltedPassword(byte[] saltValue, byte[] unsaltedPassword)
              {
                     //將salt值數(shù)組添加到hash散列數(shù)組后拼接成rawSalted數(shù)組中
                     byte[] rawSalted  = new byte[unsaltedPassword.Length + saltValue.Length];
                     unsaltedPassword.CopyTo(rawSalted,0);
                     saltValue.CopyTo(rawSalted,unsaltedPassword.Length);
                    
                     //將合并后的rawSalted數(shù)組再進行SHA1散列的到saltedPassword數(shù)組(長度為20字節(jié))
                     SHA1 sha1 = SHA1.Create();
                     byte[] saltedPassword = sha1.ComputeHash(rawSalted);
 
                     //將salt值數(shù)組在添加到saltedPassword數(shù)組后拼接成dbPassword數(shù)組(長度為24字節(jié))
                     byte[] dbPassword  = new byte[saltedPassword.Length + saltValue.Length];
                     saltedPassword.CopyTo(dbPassword,0);
                     saltValue.CopyTo(dbPassword,saltedPassword.Length);
 
                     return dbPassword;
              }
 
       }
}





主站蜘蛛池模板: 中文线码中文高清播放中 | 五月天婷婷网站 | 亚洲午夜高清 | 在线亚洲精品防屏蔽 | 亚洲国产成人久久笫一页 | 欧美一区二区激情三区 | 亚洲精品免费视频 | 午夜影视在线免费观看 | 欧美网站在线观看 | 欧美丝袜一区二区 | 天天干天天拍天天操 | 天天干天天操天天操 | 日韩美女中文字幕 | 四房色播开心网 | 婷婷丁香在线视频 | 天天射天天搞 | 伊人色婷婷 | 日韩欧美在线观看综合网另类 | 亚洲永久精品免费www52zcm男男 | 日韩毛片在线视频 | 日日夜夜网 | 亚洲图区欧美 | 亚洲自拍中文 | 日产日韩亚洲欧美综合搜索 | 在线视频中文字幕 | 天天干夜夜艹 | 亚洲综合资源 | 欧美一区二区三区激情视频 | 亚洲综合色就色手机在线观看 | 日韩综合nv一区二区在线观看 | 色婷婷99综合久久久精品 | 亚洲成人社 | 天堂国产在线观看 | 亚洲成a v人片在线观看 | 日韩3区| 日本激情在线 | 一区二区三区视频在线播放 | 日韩一区二区三区免费 | 日本亚洲欧美美色 | 天天曰天天干 | 亚洲图片欧美在线 |