ASP.NET成员身份HashAlgorithmType默认为HMACSHA256,密码哈希是否键入?

时间:2015-12-14 17:37:05

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

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

根据我在所有相关Q& A上阅读的内容,密码只使用直接SHA256进行哈希处理,而不是机器特定或键控。但是,当我在运行时检查Membership.HashAlgorithmType时,其值为" HMACSHA256"并且.NET HMACSHA256 class需要一个密钥(因为它是HMAC)并且如果没有提供给构造函数,则随机生成一个密钥。所以似乎必须要有一把钥匙。会员密码哈希键是否也是键入的?如果是,我如何跨机器使用相同的密钥?我们将非常感谢支持您答案的文件或证据。

修改

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

  

强烈建议您使用设置为Hashed或Encrypted的passwordFormat属性加密成员资格数据源中的用户密码,其中Hashed是最安全的格式。指定加密算法的加密密钥值存储在machineKey配置元素中。

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

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

如果使用随机密钥,您将无法验证密码。那么SqlMembershipProvider从哪里获取它的哈希键

1 个答案:

答案 0 :(得分:14)

在对源代码和在线进行更多挖掘后,我在SO上发现了一个问题,用户注意到他/她的SQLMembershipProvider哈希值在数据库中只有20个字节。他们应该是64岁。我检查了我的,他们也是。我试图确定一个SHA256哈希如何最终只有20个字节,并得出结论它不能。所以在我的控制台应用程序中,我尝试使用SHA1只是为了它的地狱。我将其结果与SQLMembershipProvider创建的哈希进行了比较,当然,它匹配了!我的SQLMembershipProvider使用SHA1,即使Membership.HashAlgorithmType表示它已设置为.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,即使它没有出现在intellisense中web.config。在我的web.config中passwordCompatMode="Framework40"上明确设置SqlMembershipProvider之后,我的哈希开始使用密钥HMACSHA256哈希,其中密钥是machineKey的validationKey。使用相同的验证密钥,我可以从我的控制台应用程序重现相同的哈希值。

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

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

所以这是疯狂的事情。 SqlMembershipProvider上的MSDN文档指出:

  

[passwordCompatMode]的默认值是Framework20。

因此,除非您将此隐藏属性显式声明为Framework40,否则SqlMembershipProvider使用SHA1,尽管4.0 Framework被宣传为升级到HMACSHA256。很难找到文件推断密钥来自machineKey部分......难道甚至很难发现4.0使用HMACSHA256,而不仅仅是SHA256 ...但我没有看到其他地方说明这个属性是需要。我想知道有多少开发人员在他们实际上仍然只使用SHA1时会使用更安全的HMACSHA [X]的印象?希望这有助于人们。

修改

如果<membership>元素未明确声明hashAlgorithType,则上述情况属实。您可以在上面的.NET源代码中看到它查找!Membership.IsHashAlgorithmFromMembershipConfig,它指示它是否在成员资格元素上找到hashAlgorithmType属性。因此,如果您在配置中指定<membership ... hashAlgorithmType=[x]>,我相信它不需要SqlMembershipProvider上的passwordCompatMode属性。