【问题标题】:How to properly create a SHA256 Hash?如何正确创建 SHA256 哈希?
【发布时间】:2015-12-23 11:27:15
【问题描述】:

我正在实现 SSO,我必须计算 SHA256 的字符串,然后将哈希发送回它对用户进行身份验证的端点。我通过执行以下操作使 SHA1 工作:

 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 相同?以下代码无法正常工作,这意味着它不会对另一端的用户进行身份验证:

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("-", "");

【问题讨论】:

  • 你为什么使用 var encoder = new UTF8Encoding();而不是 var encoder = new ASCIIEncoding();和第一个例子一样。是错字还是故意的?
  • 我看到了一个使用 UTF8 的例子,所以这就是原因。我实际上不确定使用哪一个。
  • 他们将根据:stackoverflow.com/questions/16994042/… 产生相同的结果

标签: c# sha256


【解决方案1】:

在我的解决方案中,我使用以下内容(准备好复制和粘贴):

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);

然后将哈希返回给服务器。

【讨论】:

  • 如果我知道所使用的哈希盐值,那将如何修改您的代码?基本上来自另一个系统,我将拥有散列密码和散列盐
  • 如果你有 hashed 盐,你什么都做不了,你需要知道它的明文。
  • 如果有散列盐,应该向 SSO 供应商索取明文盐。如果允许的话当然可以使用。通常不支持 Driveby 登录。
  • 对不起,我忘记将结果更改为十六进制字符串,现在我将其更改为返回正常字符串。
【解决方案2】:

SHA256 与“SHA256 Salted”不同。

嗯,从技术上讲,它们都是 SHA256,只是输入不同。在执行 SHA256 时,您会对数据本身进行哈希处理。当做“加盐”时(不管你使用哪个散列函数),你首先在输入中添加一些“盐”(添加可能不同,但大多数情况下它只是连接;“后缀”暗示盐是在之后添加的输入),然后对结果数据进行哈希处理。

更多详情:https://en.wikipedia.org/wiki/Salt_%28cryptography%29

【讨论】:

  • 所以为了创建一个有效的哈希,我需要知道什么被用作盐。对吗?
  • 是的,以及它们与数据结合的确切方式。
猜你喜欢
  • 2019-11-10
  • 1970-01-01
  • 2012-12-16
  • 2020-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
相关资源
最近更新 更多