3

我有一个页面需要加强安全性。我正在使用内置的 MembershipProvider 功能,目前已hashAlgorithmType设置为 SHA512。我有 BCrypt.NET 库(http://bcrypt.codeplex.com/),当我从代码中调用它的函数时,它似乎工作得很好,但我在弄清楚如何创建适当的<cryptographySettings>Web.config 中的部分让我创建一个hashAlgorithmType.

我在网上找到了以下代码片段:

<mscorlib>
    <cryptographySettings>
        <cryptoNameMapping>
            <cryptoClasses>
                <cryptoClass   MyHash="MyHashClass, MyAssembly
              Culture=neutral, PublicKeyToken=a5d015c7d5a0b012,
              Version=1.0.0.0"/>
                <cryptoClass   MyCrypto="MyCryptoClass, MyAssembly
              Culture=neutral, PublicKeyToken=a5d015c7d5a0b012,
              Version=1.0.0.0"/>
            </cryptoClasses>
            <nameEntry name="System.Security.Cryptography.HashAlgorithm"
                       class="MyHash"/>
        </cryptoNameMapping>
        <oidMap>
            <oidEntry OID="1.3.36.3.2.1"   name="MyCryptoClass"/>
        </oidMap>
    </cryptographySettings>
</mscorlib>

如果你愿意,可以称我为菜鸟,但我显然没有必要的知识来做出正面或反面。我所需要的只是一种方法来告诉会员提供者类似的东西<hashAlgorithmType="bcrypt">对应于类似string hashed = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12));加密和bool matches = BCrypt.CheckPassword(candidate, hashed);解密的东西。请告诉我有一个简单的答案。如果必须,我可以从头开始重写登录系统,但我已经有了一个工作实现,我真的很想改变它的哈希算法。

4

3 回答 3

3

我认为必须将配置模式应用于 machine.config 文件;如果您需要能够轻松推出此代码,这不一定是一个很好的举措。

您可以通过调用AddAlgorithm以编程方式将 BCrypt 加密原语注册到CryptoConfig类,并使用您以后可以使用的名称。

只要 BCrypt 哈希提供者实现了HashAlgorithn你应该能够简单地注册它,你也可以通过调用HashAlgorithm.Create(string)你用来验证它正确构建算法的名称来测试它。

会员提供者应该能够毫无问题地使用它。 这是一篇关于这个主题的好文章。

更新

(深呼吸)- 抱歉,如果这是 tl;博士。

好的,已经阅读了有关 BCrypt.Net 的密码散列的信息 - 这显然很好,并且遵循公认的做法。它也与HashAlgorithm类的工作方式完全不兼容,因为它需要额外的状态才能发挥它的魔力,并且不能简单地扩展以实现HashAlgorithm合同。

因此,您有一个选择 - 坚持MembershipProvider并使用 SHA512,因为您正在谈论加强页面的安全性,所以我认为身份验证本身可能存在问题,而不是密码的存储(其中当然,仍然必须正确完成) - 所以考虑简单地确保身份验证流量是通过 HTTPS 发送的(如果还没有的话)。

盲目地使用密码拉伸算法有其自身的问题 - 请参阅我自己最近关于此主题的 SO的回复- 如果您在服务器上进行拉伸,您最终可能会导致站点上的 DOS 攻击!

正如您所建议的,另一个选项是完全自己管理成员资格 - 因此您可以使用您想要的任何类型并手动管理密码信息的必要存储。

我的网站现在使用的算法与我从 Bruce Schneier 和 Niels Ferguson 的《实用密码学》一书中提出的 PBKDF2 非常相似,为此我使用 512 位随机盐和 SHA512(存储便宜)以及数千次迭代来散列明文。服务器对每个 appdomain 进行一次基准测试,以建立相当于毫秒范围的“保护级别”——因此,即使硬件有所改进,随着时间的推移,新散列的密码也将获得恒定级别的保护。该库也是独立的,如果我们必须在 SQL 级别生成密码记录,我已经能够将其部署到 SQL Server 2008 R2 以提供 CLR SP。

但这仅保护密码——然后您需要一个可以保护登录行为的身份验证机制;加上另一个用于保护经过身份验证的会话令牌的系统(.Net 的身份验证 Cookie 系统实际上对此非常有用)。

紧随其后,我现在花了一周时间实现SCRAM原语,然后我将其插入到我的 MVC Web 服务中进行身份验证,我计划做同样的事情来启用使用 Javascript 从 Web 浏览器登录(锁定非 JS 客户端)。客户端的关键是进行所有的哈希计算;因此我坚持使用 SHA,因为在几乎任何环境中都可以轻松获得成熟的实现(例如,我们也有 iPhone 应用程序——它们也需要进行身份验证)。

但是,在您的情况下,凭借对 MembershipProvider 的现有投资,我认为 512 位 SHA 加上 SSL 加上 Asp.Net 的身份验证 cookie 就足够了 - 只要数据库真的很安全(!)并且您没有 SQL 注入网站上的漏洞。

于 2011-06-23T22:13:06.973 回答
1

有关 HashAlgorithm 的 BCrypt 实现,请参阅我对类似问题的回答

您需要使用我的答案中的示例代码创建一个签名程序集,然后根据需要修改您的设置:

<cryptoNameMapping>
  <cryptoClasses>
    <cryptoClass MyHash="BCryptHasher, MySignedAssemblyName
                 Culture=neutral, PublicKeyToken=<my public key for singed assembly>,
                 Version=1.0.0.0"/>
  </cryptoClasses>
  <nameEntry name="System.Security.Cryptography.HashAlgorithm" class="MyHash"/>
</cryptoNameMapping>
于 2011-07-12T15:23:43.923 回答
0

为了能够注册自定义 hashAlgorythmType,您需要的第一件事是实际实现HashAlgorythm的类型。如果 BCrypt 实现了它,那是你的幸运日,但显然它没有实现它,所以这是你的问题。

确实没有解决方法,因为实现HashAlgorithm是能够像这样注册它的要求。

因此,您需要做的是围绕 BCrypt 编写一个包装器来实现HashAlgorithm,或者,这是不可能的,修改 BCrypt 本身来实现它。

除非你真的非常幸运,并且 BCrypt 的编写方式很容易进行这种修改,否则它可能需要一些不平凡的努力。

于 2011-06-23T22:56:59.427 回答