我有一个使用的ASP.NET 4.5 Web应用程序SqlMembershipProvider
.在开发期间,有人放入passwordFormat="Clear"
配置,导致密码以明文保存.我想删除它并启用密码哈希,但我想确保不使用机器特定的或自动生成的密钥生成哈希.
根据我在所有相关问答中所读到的内容,密码只需使用直接SHA256进行哈希处理,而不是机器特定或键控.但是,当我在运行时检查Membership.HashAlgorithmType时,其值为"HMACSHA256",并且.NET HMACSHA256
类需要一个键(因为它是HMAC)并随机生成一个(如果没有提供给构造函数).所以似乎必须要有一把钥匙.会员密码哈希键是否也是键入的?如果是,我如何跨机器使用相同的密钥?将非常感谢支持您答案的文档或证据.
编辑
根据这个关于"保护成员身份"的MSDN页面,machineKey元素确实控制了哈希键:
强烈建议您使用设置为Hashed或Encrypted的passwordFormat属性加密成员资格数据源中的用户密码,其中Hashed是最安全的格式.指定加密算法的加密密钥值存储在machineKey配置元素中.
但是,我尝试在web.config中设置机器密钥验证密钥,它仍然生成与设置之前相同的密码哈希,因此它似乎没有任何效果.
我一直在查看SqlMembershipProvider源代码,据我所知,它确实使用了键控哈希.当然,这是.Net 4.6.1的来源,我正在运行4.5.我已经复制了EncodePassword
源代码并对其进行了修改,因此它可以在控制台应用程序中运行,在我的控制台应用程序中,我仍然获得与MembershipProvider结果(在同一台机器上)相同的密码和盐值的哈希值.
如果它使用随机密钥,您将无法验证密码.那么SqlMembershipProvider从哪里获取它的哈希键?
在更深入地了解源代码和在线之后,我在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
从一个名为config的属性设置passwordCompatMode
,这属于SqlMembershipProvider
,即使它没有出现在web.config中的intellisense中.有一次,我明确设置passwordCompatMode="Framework40"
的SqlMembershipProvider
在我的web.config,我的哈希开始使用密钥HMACSHA256散列结果,其中的关键是的machineKey的validationKey的.使用相同的验证密钥,我可以从我的控制台应用程序重现相同的哈希值.
作为问题的确认,当我删除passwordCompatMode="Framework40"
属性时,然后在调试器中检查一个实例SqlMembershipProvider
,我可以看到:
_LegacyPasswordCompatibilityMode = "Framework20" s_HashAlgorithm = "SHA1" (!!!)
所以这是疯狂的事情.SqlMembershipProvider上的MSDN doc 说明:
[codeCompatMode]的默认值是Framework20.
因此,除非您明确声明此隐藏属性Framework40
,否则SqlMembershipProvider
尽管将4.0 Framework广告为升级到HMACSHA256,但仍使用SHA1.很难找到文件推断密钥来自machineKey部分......难道甚至很难发现4.0使用HMACSHA256,而不仅仅是SHA256 ...但我没有看到其他地方声明这个属性是必需的.我想知道有多少开发人员在他们实际上仍然只使用SHA1时使用更安全的HMACSHA [X]的印象?希望这有助于人们.
编辑
如果
元素没有明确声明,则上述情况属实hashAlgorithType
.您可以在上面的.NET源代码中看到它查找!Membership.IsHashAlgorithmFromMembershipConfig
哪个指示它是否hashAlgorithmType
在成员资格元素上找到了该属性.因此,如果您
在配置中指定,我相信它不需要passwordCompatMode
SqlMembershipProvider上的属性.