一種密碼加密存儲方案:加鹽哈希

今天來聊一聊一種被廣泛使用的密碼加密存儲方案:加鹽哈希。

本文包含以下內容:

  • 什麼是鹽?
  • 什麼是哈希演算法?
  • 加密與校驗過程。
  • C#實現。

 什麼是鹽?

 In cryptography, a salt is random data that is used as an additional input to a one-way function that hashes data, a password or passphrase. — From Wiki.

  其實說白了,鹽就是在密碼學中用於加密的隨機數據。

什麼是哈希演算法?

A cryptographic hash function (CHF) is a hash function that is suitable for use in cryptography. It is a mathematical algorithm that maps data of arbitrary size (often called the “message”) to a bit string of a fixed size (the “hash value”, “hash”, or “message digest”) and is a one-way function, that is, a function which is practically infeasible to invert. — From Wiki.

  密碼哈希函數(CHF)是適用於密碼學的哈希函數。 這是一種數學演算法,可將任意大小的數據(通常稱為「消息」)映射到固定大小的字元串上(「哈希值」,「哈希」或「消息摘要」),並且是單向的函數,不可逆轉。這裡包含了密碼哈希函數重要的兩個特點:1. 可將任意大小數據映射到固定大小數據上。2. 不可逆轉。參考下面的圖片(源於Wiki),不管input長短,經過哈希演算法之後,都會生成一個固定長短的哈希值。並且在input上一個微小的改變,對哈希結果的影響都是巨大的。

 

加密與校驗過程

 

C#實現

生成鹽

 

 1         /// <summary>
 2         /// 生成鹽
 3         /// </summary>
 4         /// <returns></returns>
 5         public static byte[] GetSalt()
 6         {
 7             //Buffer storage.
 8             var salt = new byte[8];
 9             using (var provider = new RNGCryptoServiceProvider())
10             {
11                 provider.GetBytes(salt);
12             }
13             return salt;
14         }

 

合併鹽與明文

 

 1         /// <summary>
 2         /// 合併鹽與明文
 3         /// </summary>
 4         /// <param name="byte1"></param>
 5         /// <param name="byte2"></param>
 6         /// <returns></returns>
 7         private static byte[] CombineByteArray(byte[] byte1, byte[] byte2)
 8         {
 9             var ret = new byte[byte1.Length + byte2.Length];
10             Array.Copy(byte1, 0, ret, 0, byte1.Length);
11             Array.Copy(byte2, 0, ret, byte1.Length, byte2.Length);
12             return ret;
13         }

 

哈希合併後數據

 

 1         /// <summary>
 2         /// Hash Salted input and salt
 3         /// </summary>
 4         /// <param name="input">input</param>
 5         /// <param name="salt">salt</param>
 6         /// <returns>return 32 bytes hashed values</returns>
 7         public static byte[] HashSalted256(string input, byte[] salt)
 8         {
 9             var bytes = Encoding.Unicode.GetBytes(input);
10             byte[] hashSaltedValue = null;
11             using (var sha256 = new SHA256CryptoServiceProvider())
12             {
13                 var saltedInput = CombineByteArray(bytes, salt);
14                 hashSaltedValue = sha256.ComputeHash(saltedInput);
15             }
16             return hashSaltedValue;
17         }

 

 

參考鏈接:

//en.wikipedia.org/wiki/Salt_(cryptography)

//en.wikipedia.org/wiki/Cryptographic_hash_function