【问题标题】:SHA1CryptoServiceProvider changed in .NET 4SHA1CryptoServiceProvider 在 .NET 4 中更改
【发布时间】:2010-05-31 20:40:39
【问题描述】:

我目前正在尝试将我的一个项目从 .NET 3.5 升级到 .NET 4.0

一切进展顺利,所有代码均已编译,所有测试均已通过。
然后我在部署到暂存环境时遇到了问题。
突然间我的登录不再起作用了。

似乎我的 SHA1 散列密码在 .NET 4 中的散列方式不同。

我正在使用 SHA1CryptoServiceProvider:

SHA1CryptoServiceProvidercryptoTransformSHA1 = new SHA1CryptoServiceProvider();

为了测试,我创建了一个带有 2 个控制台应用程序的新 Visual Studio 项目。
第一个针对 .NET Framework 3.5,第二个针对 4.0。
我在两者中都运行了完全相同的哈希代码,并产生了不同的结果。

为什么会发生这种情况,我该如何解决?
考虑到我不知道它们是什么,我显然无法更新所有用户的密码。

任何帮助将不胜感激。

代码示例

public static class SHA1Hash
{

    public static string Hash(string stringToHash)
    {
        return (Hash(stringToHash, Encoding.Default));
    }

    public static string Hash(string stringToHash, Encoding enc)
    {
        byte[] buffer = enc.GetBytes(stringToHash + stringToHash.Reverse());
        var cryptoTransformSHA1 = new SHA1CryptoServiceProvider();
        string hash = BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer));
        return hash;
    }
}

【问题讨论】:

  • Login fails after upgrade to ASP.net 4.0 from 3.5 的可能重复项——包括解决方案
  • 不幸的是,情况并非如此。这是关于 FormsAuthenticationCookies 和 ViewState 的,只是“如果您运行混合的 ASP.NET 2.0/ASP.NET 4”的问题。但是当我认为这是我的解决方案
  • 你能解决 AsymetricHash/Hash 的混淆吗?只是为了安全。
  • Henk,你在这里解决了我的问题。 String.Reverse 是一个反转字符串的 Linq 函数。然而,它返回一个 IEnumerable。尝试调用 "StringValue".Reverse().ToString() 只会返回类型名称。由于这些在 .NET 3.5 和 .NET 4.0 中的类型名称不同,因此我得到了不同的散列值。对不起.NET 4.0,你一直做得很好。感谢大家的帮助
  • 呃。你应该检查你的用户数据库以确保你没有搞砸它:D每个人都可能有相同的哈希......:D

标签: cryptography .net-4.0 sha1


【解决方案1】:

其中一个 cmets 让我找到了代码中的错误。
在创建要散列的字节数组时,我试图在字符串后面附加其自身的反转版本。

例如给哈希“密码”我实际上会哈希“passworddrowssap”

但是我的代码有一个小错误:

byte[] buffer = enc.GetBytes(stringToHash + stringToHash.Reverse()); 

.Reverse() 是一种可以反转字符串的 Linq 扩展方法。
但是它不返回字符串,而是返回:

IEnumerable<Char>

在这种类型上调用 .ToString() 实际上会返回:

System.Linq.Enumerable+d__99`1[System.Char]

在 .NET 4.0 中做同样的事情会返回

System.Linq.Enumerable+d__a0`1[System.Char]

因此我的密码被不同地散列。
我应该通过字节数组创建的是:

byte[] buffer = enc.GetBytes(stringToHash + new String(stringToHash.Reverse().ToArray()));

【讨论】:

    【解决方案2】:

    听起来可能是字符编码问题。确保被散列的字符串采用您期望的编码 [utf8, ansi etc](如果是,请确保旧环境也是。)

    -奥辛

    【讨论】:

    • 我一直在使用 Encoding.Default。我尝试指定编码,但以下方法均无效:Encoding.ASCII、Encoding.BigEndianUnicode、Encoding.Unicode、Encoding.UTF32、Encoding.UTF7、Encoding.UTF8
    • 散列在字节流级别工作 - 我不确定你是否理解我的意思。您在哪里指定编码?重要的是两个系统都被验证为向 sha1 类提供相同的 bytes
    • 请查看我调用的方法的代码示例。两个站点都在完全相同的服务器上运行,所以我不确定编码会在哪里改变。如何验证两个系统向 sha1 类提供相同的字节?根据我上面的代码示例,我可以检查 buffer.Length 吗?
    • Encoding.Default 在每个系统上可能不同(而您的用户哈希显然是不变的。)在每个系统上使用简单的控制台应用程序(或使用 powershell)验证默认编码。我的默认编码是 windows-1252;其他人可能会有所不同。
    • (顺便说一句,如果哈希不同 - 你必须假设字节流不同。sha1算法在框架之间没有改变)
    猜你喜欢
    • 1970-01-01
    • 2013-02-27
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 2017-11-22
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    相关资源
    最近更新 更多