c# - ASP.NET 成员资格 HashAlgorithmType 默认为 HMACSHA256,那么密码散列是键控的吗?

标签 c# asp.net hash asp.net-membership

我有一个使用 SqlMembershipProvider 的 ASP.NET 4.5 Web 应用程序。在开发过程中,有人将 passwordFormat="Clear" 放入配置中,导致密码以明文形式保存。我想删除它并启用密码散列,但我想确保散列不是使用特定于机器或自动生成的 key 生成的。

根据我在所有相关问答中所读到的内容,密码只是使用直接 SHA256 进行哈希处理,而不是特定于机器或 key 的。但是,当我在运行时检查 Membership.HashAlgorithmType 时,它​​的值为“HMACSHA256”和 .NET HMACSHA256 class需要一个 key (因为它是 HMAC),如果没有提供给构造函数,则随机生成一个。所以看来一定有一把 key 参与其中。那么成员(member)密码哈希值是否加密?如果是,我如何跨机器使用相同的 key ?支持您的回答的文档或证据将不胜感激。

编辑

根据 this MSDN page on "Securing Membership" ,machineKey 元素确实控制哈希键:

It is highly recommended that you encrypt user passwords in the membership data source using a passwordFormat attribute set to Hashed or Encrypted, where Hashed is the most secure format. The encryption key values for the specified encryption algorithm are stored in the machineKey configuration element.

但是,我尝试在 web.config 中设置机器 key 验证 key ,它仍然生成与设置之前相同的密码哈希,所以它似乎没有效果。

我也一直在看 SqlMembershipProvider source code据我所知,它确实使用了键控哈希。当然这是 .Net 4.6.1 的来源,我正在运行 4.5。我已经复制了 EncodePassword 源代码并对其进行了修改,以便它可以在控制台应用程序中运行,而在我的控制台应用程序中,我仍然得到与 MembershipProvider 结果(在同一台机器上)不同的哈希值密码和盐值。

如果它使用随 secret 钥,您将无法验证密码。那么 SqlMembershipProvider 从哪里得到它的哈希键呢??

最佳答案

在深入研究源代码和在线之后,我在 SO 上发现了一个问题,用户注意到了他/她的 SQLMembershipProvider哈希值在数据库中只有 20 个字节。他们应该是 64 岁。我检查了我的,他们也是。我试图确定 SHA256 哈希如何最终只有 20 个字节,并得出它不能的结论。所以在我的控制台应用程序中,我尝试只使用 SHA1 来解决这个问题。我将其结果与 SQLMembershipProvider 创建的哈希进行了比较果然,它匹配了!我的SQLMembershipProvider尽管 Membership.HashAlgorithmType 仍在使用 SHA1表示它设置为 .NET 4.0 默认值“HMACSHA256”。

这是我阅读源代码派上用场的地方。我记得我从我的控制台应用程序中删除了一个条件部分,它在创建哈希算法类时检查某些遗留模式。

        private HashAlgorithm GetHashAlgorithm() {
        if (s_HashAlgorithm != null)
            return HashAlgorithm.Create(s_HashAlgorithm);

        string temp = Membership.HashAlgorithmType;
        if (_LegacyPasswordCompatibilityMode == MembershipPasswordCompatibilityMode.Framework20 &&
            !Membership.IsHashAlgorithmFromMembershipConfig &&
            temp != "MD5")
        {
            temp = "SHA1";
        }
        HashAlgorithm hashAlgo = HashAlgorithm.Create(temp);
        if (hashAlgo == null)
            RuntimeConfig.GetAppConfig().Membership.ThrowHashAlgorithmException();
        s_HashAlgorithm = temp;
        return hashAlgo;
    }

经过更多挖掘,我确定了 _LegacyPasswordCompatibilityMode从名为 passwordCompatMode 的配置属性中设置这属于 SqlMembershipProvider ,即使它没有出现在 web.config 的智能感知中。一旦我明确设置 passwordCompatMode="Framework40"SqlMembershipProvider 上在我的 web.config 中,我的散列开始使用键控 HMACSHA256 散列,其中键是 machineKey 的 validationKey。使用相同的验证 key ,然后我能够从我的控制台应用程序中重现相同的哈希值。

作为问题的确认,当我删除 passwordCompatMode="Framework40"属性,然后在调试器中检查 SqlMembershipProvider 的一个实例,我可以看到:

_LegacyPasswordCompatibilityMode = "Framework20"
s_HashAlgorithm = "SHA1" (!!!)

这就是疯狂的事情。 SqlMembershipProvider 上的 MSDN 文档状态:

The default value [for passwordCompatMode] is Framework20.

所以除非你明确声明这个晦涩的属性为Framework40 , SqlMembershipProvider尽管 4.0 框架被宣传为升级到 HMACSHA256,但仍使用 SHA1。很难找到推断 key 来自 machineKey 部分的文档……该死的,甚至很难发现 4.0 使用 HMACSHA256,而不仅仅是 SHA256……但我没有看到其他任何地方说明此属性是必需的。我想知道有多少开发人员认为他们使用的是更安全的 HMACSHA[X],而实际上他们仍然只使用 SHA1?希望这对人们有所帮助。

编辑

如果 <membership> 以上为真元素未明确声明 hashAlgorithType .您可以在上面的 .NET 源代码中看到它查找 !Membership.IsHashAlgorithmFromMembershipConfig。这表明它是否找到了 hashAlgorithmType membership 元素上的属性。因此,如果您指定 <membership ... hashAlgorithmType=[x]>在你的配置中,我相信它不需要 passwordCompatMode SqlMembershipProvider 上的属性。

关于c# - ASP.NET 成员资格 HashAlgorithmType 默认为 HMACSHA256,那么密码散列是键控的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34273233/

相关文章:

c# - 有没有办法指定在站点范围内使用哪个字符串比较?

encryption - 将字符串哈希为特定长度

c# - 如何快速找到我的 EDMX 模型中的特定表?

c# - 过时类的使用

c# - 如何将 HostControl 实例传递给 TopShelf 中的自定义主机服务?

javascript 使用一个控件切换显示/隐藏 div

c# - 不带参数的 Excel DNA 函数在 Excel 函数向导中仍显示一个参数

c# - Ajax Accordion 、数据集中的特定数据、多个数据集或数据集中的不同数据可能吗?

c# - 如何对 `string.Empty` 进行哈希处理?

oracle - 在perl脚本中调用带有输入参数和输出光标的存储过程