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

明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

詳細(xì)說(shuō)明對(duì)密碼執(zhí)行散列與 salt 運(yùn)算方法

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

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

 

Credentials.cs

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





主站蜘蛛池模板: 日韩精品一区二区三区中文3d | 日本高清视频网站www | 色国产视频 | 天天看片天天干 | 情不自禁完整版在线观看免费 | 中文亚洲欧美 | 窝窝午夜色视频国产精品东北 | 欧美午夜在线视频 | 欧美亚洲国产精品久久 | 青春草视频下载 | 日韩欧美小视频 | 色噜噜狠狠一区二区三区 | 日韩欧美国产视频 | 日韩无人区码卡二卡3卡4卡介绍 | 亚洲一区二区三区精品影院 | 天天天天天天干 | 特片伦理在线网站 | 天天爽夜夜爽天天做夜夜做 | 中文字幕在线免费视频 | 欧美系列第一页 | 欧美综合精品一区二区三区 | 中文字幕免费在线视频 | 一区二区久久 | 亚洲影视在线 | 青青青爽视频在线观看入口 | 小草青青免费影视观看 | 日韩色天使综合色视频 | 小说区图片区综合久久亚洲 | 涩涩五月天 | 亚洲欧美日本韩国综合在线观看 | 亚洲区 欧美区 | 在线观看91精品国产下载 | 日本在线视频网 | 手机看片久久国产免费不卡 | 性欧美人 | 色网在线观看 | 欧美性视频在线 | 欧美在线视频第一页 | 日本三区四区免费高清不卡 | 日产毛片 | 啪啪免费看视频 |