如何正确创建SHA256哈希?

问题描述:

我正在实现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 –

SHA256是不一样的“SHA256咸鱼”。

嗯,从技术上讲,它们都是SHA256,它只是输入的不同。在做SHA256时,你自己散列数据。在做“盐化”(无关你使用哪个哈希函数)时,首先向输入添加一些“盐”(加法可能不同,但大多数情况下它只是串联;“后缀”暗示盐在添加之后添加输入),然后散列结果数据。

更多细节:https://en.wikipedia.org/wiki/Salt_%28cryptography%29

+0

所以为了创建一个有效的散列,我需要知道盐是什么。正确? – xaisoft

+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登录通常在任何地方都不受支持。 –