C#中的哈希字符串


90

尝试在中获取哈希字符串时遇到问题c#

我已经尝试过一些网站,但是大多数网站都使用文件来获取哈希值。其他用于字符串的有点太复杂。我找到了用于Windows的Web身份验证示例,如下所示:

FormsAuthentication.HashPasswordForStoringInConfigFile(tbxPassword.Text.Trim(), "md5")

我需要使用散列来使包含文件名的字符串更安全。我怎样才能做到这一点?

例:

string file  = "username";
string hash = ??????(username); 

我应该使用其他哈希算法而不是“ md5”吗?

Answers:


183
using System.Security.Cryptography;

public static byte[] GetHash(string inputString)
{
    using (HashAlgorithm algorithm = SHA256.Create())
        return algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString));
}

public static string GetHashString(string inputString)
{
    StringBuilder sb = new StringBuilder();
    foreach (byte b in GetHash(inputString))
        sb.Append(b.ToString("X2"));

    return sb.ToString();
}

补充说明

  • 由于MD5和SHA1是过时且不安全的算法,因此该解决方案使用SHA256。或者,您可以使用注释中指出的BCryptScrypt
  • 另外,如注释中所指出的,考虑“撒盐”您的哈希并使用经过验证的密码算法。

46
请勿使用MD5或SHA1,它们是过时且不安全的算法。至少或什至最好使用BCrypt或Scrypt使用SHA256。
穆罕默德·雷汉


6
@Muh它可以轻松地用于校验和,因为它比SHA512快得多。但是确实要存储密码,不建议这样做,这是正确的。
LuckyLikey

5
b.ToString("X2")是什么意思?
Bilal Fazlani


60

下面的代码是获取用于密码存储目的的哈希字符串的最快方法:

    internal static string GetStringSha256Hash(string text)
    {
        if (String.IsNullOrEmpty(text))
            return String.Empty;

        using (var sha = new System.Security.Cryptography.SHA256Managed())
        {
            byte[] textData = System.Text.Encoding.UTF8.GetBytes(text);
            byte[] hash = sha.ComputeHash(textData);
            return BitConverter.ToString(hash).Replace("-", String.Empty);
        }
    }

备注:

  • 如果经常调用该方法,sha则应将变量的创建重构到类字段中;
  • 输出显示为编码的十六进制字符串;

SHA1Managed上课不是很贵。它消耗约130个字节并将其初始化为某个静态值,仅此而已。因此在大多数情况下都不会出现性能问题。
Earth Engine

1
SHA1Managed就是IDisposable,因此需要来包装它的使用成using块。
Earth Engine

目的Dispose方法是清除内部缓冲区。否则,将有遭受内存攻击的风险。
Earth Engine

3
@MuhammadRehanSaeed当我SHA1Managed说不昂贵时,我的意思是它的创造不是。同样,哈希算法也不是必须的。当您要查找碰撞时,它仅(极其)昂贵。
Earth Engine

1
@King_Fisher-这是不可能的!哈希是一种单向函数,信息会丢失。如果需要解密,则需要使用加密方法而不是散列。顺便说一句,加密密码是一个坏习惯。
andrew.fox '18

8

我不太了解您提出的问题的全部内容,但是如果您只需要字符串的哈希值,那么就很容易理解。

只需使用GetHashCode方法。

像这样:

string hash = username.GetHashCode();

1
是的,它在寻找什么。但是它的代码是个大错误。显示类似int hash =“ username” .GetHasCode();的代码。
Edy Cu

3
为什么将用户名放在双引号中?这将获取单词“ username”的哈希值,以及用户名变量中的内容。
西里尔·古普塔

14
不要存储GetHashCode的值,32x和64x有所不同
Slava 2013年

12
这是创建密码哈希的一种坏方法。使用GetHashCode(),您不能假定将在不同的计算机上生成相同的数字。使用Sha1哈希方法或其他方法(我将在稍后发布示例)
andrew.fox 2014年

2
应该注意的GetHashCode是,这不是密码安全的哈希算法。至少使用SHA256或什至更好地使用BCrypt或Scrypt以获得安全算法。
穆罕默德·雷汉

5

我认为您要寻找的不是哈希而是加密。使用散列时,您将无法从“散列”变量中检索原始文件名。使用加密就可以了,而且很安全。

有关.NET中加密的更多信息,请参见带有VB.NET的ASP.NET中的AES


是的,我认为是加密,但是我只想比较结果哈希值。重定向页面之后。
Edy Cu

您想将散列文件名与什么进行比较?
Pieter van Ginkel

1
//Secure & Encrypte Data
    public static string HashSHA1(string value)
    {
        var sha1 = SHA1.Create();
        var inputBytes = Encoding.ASCII.GetBytes(value);
        var hash = sha1.ComputeHash(inputBytes);
        var sb = new StringBuilder();
        for (var i = 0; i < hash.Length; i++)
        {
            sb.Append(hash[i].ToString("X2"));
        }
        return sb.ToString();
    }

3
请勿通过此链接使用SHA1,SHA1是过时且不安全的算法。至少或什至最好使用BCrypt或Scrypt使用SHA256。
穆罕默德·雷汉·赛义德


1

如果性能不是主要问题,则还可以使用以下任何一种方法:(
如果希望散列字符串为大写,请替换"x2""X2"。)

public static string SHA256ToString(string s) 
{
    using (var alg = SHA256.Create())
        return string.Join(null, alg.ComputeHash(Encoding.UTF8.GetBytes(s)).Select(x => x.ToString("x2")));
}

要么:

public static string SHA256ToString(string s)
{            
    using (var alg = SHA256.Create())
        return alg.ComputeHash(Encoding.UTF8.GetBytes(s)).Aggregate(new StringBuilder(), (sb, x) => sb.Append(x.ToString("x2"))).ToString();
}

0

有史以来最短,最快的方法。只有1行!

    public static string StringSha256Hash(string text) =>
        string.IsNullOrEmpty(text) ? string.Empty : BitConverter.ToString(new System.Security.Cryptography.SHA256Managed().ComputeHash(System.Text.Encoding.UTF8.GetBytes(text))).Replace("-", string.Empty);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.