2015-09-25 138 views
0

我正在實現SSO,我必須計算SHA256具有一個字符串,並將散列發送回並驗證用戶身份的端點。我SHA1做的工作如下:如何正確創建SHA256哈希?

var hash = SHA1.Create(); 
var encoder = new ASCIIEncoding(); 
byte[] combined = encoder.GetBytes(encryptedTokenStr); 
hash.ComputeHash(combined); 
string delimitedHexHash = BitConverter.ToString(hash.Hash); 
string completedSha1Hash = delimitedHexHash.Replace("-", ""); 

但如果我改變了哈希算法類型來SHA256和其他系統正哈希算法更改爲SHA256 Salted (Suffix)不知道這是否是一樣的SHA256?下面的代碼不能正常工作,這意味着它不會authenicate用戶的另一面:

var hash = SHA256.Create(); 
var encoder = new UTF8Encoding(); 
byte[] combined = encoder.GetBytes(encryptedTokenStr); 
hash.ComputeHash(combined); 
string delimitedHexHash = BitConverter.ToString(hash.Hash); 
string completedSha1Hash = delimitedHexHash.Replace("-", ""); 
+0

你爲什麼使用var encoder = new UTF8Encoding();而不是var encoder = new ASCIIEncoding();如在第一個例子中那樣。這是一個錯字還是故意的? –

+0

我看到一個使用UTF8的例子,所以這就是爲什麼。我其實不確定使用哪一個。 – xaisoft

+0

他們將產生相同的結果根據:http://stackoverflow.com/questions/16994042/difference-between-encoding-utf8-getbytes-and-utf8encoding-default-getbytes#16994086 –

回答

1

SHA256是不一樣的「SHA256鹹魚」。

嗯,從技術上講,它們都是SHA256,它只是輸入的不同。在做SHA256時,你自己散列數據。在做「鹽化」(無關你使用哪個哈希函數)時,首先向輸入添加一些「鹽」(加法可能不同,但大多數情況下它只是串聯;「後綴」暗示鹽在添加之後添加輸入),然後散列結果數據。

更多細節:https://en.wikipedia.org/wiki/Salt_%28cryptography%29

+0

所以爲了創建一個有效的散列,我需要知道鹽是什麼。正確? – xaisoft

+0

是的,以及它們與數據結合的確切方式。 –

0

在我的解決方案我用下面(複製和粘貼準備):

using System; 
using System.Security.Cryptography; 
using System.Text; 

public string ComputeHash(string plainText, byte[] salt = null) 
    { 
     int minSaltLength = 4; 
     int maxSaltLength = 16; 

     byte[] saltBytes = null; 

     if (salt != null) 
     { 
      saltBytes = salt; 
     } 
     else 
     { 
      Random r = new Random(); 
      int len = r.Next(minSaltLength, maxSaltLength); 
      saltBytes = new byte[len]; 

      using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) 
      { 
       rng.GetNonZeroBytes(saltBytes); 
      } 
     } 
     byte[] plainData = ASCIIEncoding.UTF8.GetBytes(plainText); 
     int plainLength = plainData.Length; 
     int saltLength = saltBytes.Length; 
     byte[] plainDataAndSalt = new byte[plainLength + saltLength]; 
     Array.Copy(plainData, 0, plainDataAndSalt, 0, plainLength); 
     Array.Copy(saltBytes, 0, plainDataAndSalt, plainLength, saltLength); 

     byte[] hashValue = null; 

     using (SHA256Managed sha2 = new SHA256Managed()) 
     { 
      hashValue = sha2.ComputeHash(plainDataAndSalt); 
     } 

     int hashLength = hashValue.Length; 
     byte[] result = new byte[hashLength + saltLength]; 
     Array.Copy(hashValue, 0, result, 0, hashLength); 
     Array.Copy(saltBytes, 0, result, hashLength, saltLength); 

     return ASCIIEncoding.UTF8.GetString(result); 
    } 

解決你的問題/問題:

string hash = hash.ComputeHash("your string"); 

或者,如果服務器爲你提供鹽串:

byte[] salt = ASCIIEncoding.UTF8.GetBytes("server salt string in plaintext"); 
string hash = hash.ComputeHash("your string to hash", salt); 

然後將散列返回給服務器。

+0

如果我知道所使用的散列鹽值,那麼如何修改您的代碼?基本上來自其他系統,我將有散列密碼和散列鹽 – xaisoft

+0

如果你有*散列*鹽,你不能做一件事,你需要知道它的明文。 –

+0

如果存在散列鹽,應向SSO供應商索要純文本鹽。如果允許使用它當然。 Driveby登錄通常在任何地方都不受支持。 –