简体   繁体   English

在C#ASP.NET中添加自定义hashAlgorithmType

[英]Adding a custom hashAlgorithmType in C# ASP.NET

I've got a page that I need to beef up security on. 我有一个页面,我需要加强安全性。 I'm using the built-in MembershipProvider functionality and currently have hashAlgorithmType set to SHA512. 我正在使用内置的MembershipProvider功能,并且当前将hashAlgorithmType设置为SHA512。 I've got the BCrypt.NET library (http://bcrypt.codeplex.com/) and it seems to be working nicely when I call its functions from code but I'm having the worst time figuring out how to create the appropriate <cryptographySettings> section in Web.config to let me create a hashAlgorithmType . 我有BCrypt.NET库(http://bcrypt.codeplex.com/),当我从代码调用它的函数时似乎工作得很好但是我遇到了最糟糕的时间来弄清楚如何创建合适的Web.config中的<cryptographySettings>部分让我创建一个hashAlgorithmType

I found the following code snippet on the web: 我在网上找到了以下代码段:

<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>

Call me a noob if you want, but I apparently don't have the requisite knowledge to make heads or tails of that. 如果你愿意,可以叫我一个菜鸟,但我显然没有必要的知识来做出正面或反面。 All I need is a method to tell the membership provider that something like <hashAlgorithmType="bcrypt"> corresponds to something like string hashed = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12)); 我需要的是一种方法来告诉成员资格提供者像<hashAlgorithmType="bcrypt">这样的东西对应于string hashed = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12)); to encrypt and bool matches = BCrypt.CheckPassword(candidate, hashed); 加密和bool matches = BCrypt.CheckPassword(candidate, hashed); to decrypt. 解密。 Please tell me there's an easy answer. 请告诉我一个简单的答案。 I can rewrite the login system from scratch if I have to, but I already have a working implementation that I'd really like to just change the hashing algorithm of. 如果必须的话,我可以从头开始重写登录系统,但我已经有了一个工作实现,我真的只想改变哈希算法。

I believe that config pattern must be applied to the machine.config file; 我相信配置模式必须应用于machine.config文件; which isn't necessarily a great move if you need to be able to roll out this code easily. 如果您需要能够轻松地推出此代码,这不一定是一个很好的举措。

You can programmatically register the BCrypt encryption primitive(s) with the CryptoConfig class through a call to AddAlgorithm with a name that can you can later use. 您可以通过调用AddAlgorithm以编程方式使用CryptoConfig类注册BCrypt加密原语,该名称可以在以后使用。

So long as the BCrypt hash provider implements HashAlgorithn you should be able to register it simply, you can also test this by calling HashAlgorithm.Create(string) with the name you use to verify that it builds the algorithm correctly. 只要BCrypt哈希提供程序实现HashAlgorithn你应该能够简单地注册它,你也可以通过调用HashAlgorithm.Create(string)来测试它,你用它来验证它是否正确构建了算法。

The membership provider should then be able to use it without issue. 然后,会员提供商应该可以毫无问题地使用它。 Here's a good article about this topic. 这是一篇关于这个主题的好文章

Update 更新

(deep breath) - apologies if this is tl;dr. (深呼吸) - 道歉,如果这是tl;博士。

Okay, so having read around about BCrypt.Net's password hashing - it's obviously good, and follows accepted practise. 好的,所以阅读了有关BCrypt.Net的密码哈希 - 它显然是好的,并遵循公认的做法。 It is, also, completely incompatible with how the HashAlgorithm class works because it requires additional state in order to work it's magic, and can't simply be extended to implement the HashAlgorithm contract. 它也与HashAlgorithm类的工作方式完全不兼容,因为它需要额外的状态才能实现它的魔力,并且不能简单地扩展为实现HashAlgorithm契约。

Thus, you have a choice - stick with MembershipProvider and use SHA512 as you already are - you're talking about beefing up security on a page , so I'm thinking there might be issues with authentication itself, rather than the storage of passwords (which must, of course, still be done properly) - so consider simply making sure that the authentication traffic is sent over HTTPS if it's not already. 因此,您可以选择 - 坚持使用MembershipProvider并使用SHA512 - 您正在谈论加强页面上的安全性,所以我认为可能存在身份验证本身的问题,而不是密码的存储(当然,这仍然必须正确完成) - 所以考虑简单地确保通过HTTPS发送身份验证流量(如果尚未发送)。

Using password stretching algorithms blindly has its own issues - see the responses to my own recent SO on this topic - if you do the stretching on the server you could potentially end up causing a DOS attack on the site! 盲目使用密码拉伸算法有其自身的问题 - 请参阅我自己最近对此主题的回应 - 如果你在服务器上进行拉伸,你可能最终导致对网站的DOS攻击!

The other option is, as you've suggested, to manage the membership entirely yourself - thus you can use whichever types you want and manage the necessary storage of the password information manually. 正如您所建议的那样,另一个选择是完全自己管理会员资格 - 因此您可以使用您想要的任何类型并手动管理必要的密码信息存储。

My sites now use an algorithm very similar to PBKDF2 that I lifted from Bruce Schneier and Niels Ferguson's book Practical Cryptography, for which I use 512 bit random salt and SHA512 (storage is cheap) plus many thousands of iterations to hash a clear text. 我的网站现在使用的算法非常类似于PBKDF2,我从Bruce Schneier和Niels Ferguson的书“Practical Cryptography”中提取,我使用512位随机盐和SHA512(存储便宜)加上数千次迭代来散列明文。 The server benchmarks itself once per appdomain to establish 'levels' of protection that equate to millisecond ranges - thus over time newly hashed passwords will receive a constant level of protection even if the hardware improves. 服务器每个appdomain对自己进行一次基准测试,以建立相当于毫秒范围的“保护级别” - 因此,随着时间的推移,即使硬件改进,新的散列密码也将获得恒定的保护级别。 The library is standalone, too, and I've been able to deploy it to SQL Server 2008 R2 to provide CLR SPs if we have to generate password records at the SQL level. 该库也是独立的,如果我们必须在SQL级别生成密码记录,我已经能够将它部署到SQL Server 2008 R2以提供CLR SP。

But this only protects the passwords - you then need an authentication mechanism that can protect the act of logging in; 但这仅保护密码 - 然后您需要一种可以保护登录行为的身份验证机制; plus another system for protecting the authenticated session token (.Net's Authentication Cookie system is actually pretty good for this). 加上另一个用于保护经过身份验证的会话令牌的系统(.Net的Authentication Cookie系统实际上非常有用)。

Following on from that SO I have now spent a week implementing SCRAM primitives that I have then plugged into my MVC web services for authentication, and I plan to do the same to enable login from the web browser using Javascript (locking out non-JS clients). 接下来我已经花了一周的时间实现SCRAM原语,然后我插入我的MVC Web服务进行身份验证,我打算做同样的事情来启用使用Javascript从Web浏览器登录(锁定非JS客户端) )。 The key there being the client is doing all the hash calculations; 客户端的关键是进行所有哈希计算; thus I've stuck to SHA because mature implementations are readily available in practically any environment (eg we have iPhone apps too - and they need to authenticate as well). 因此我坚持使用SHA,因为成熟的实现几乎可以在任何环境中使用(例如我们也有iPhone应用程序 - 他们也需要进行身份验证)。

In your case, however, with the existing investment in the MembershipProvider, I would consider 512 bits of SHA plus SSL plus Asp.Net's auth cookie sufficient - so long as the database is really secure(!) and you've got no SQL injection holes in the site. 但是,在你的情况下,对于MembershipProvider的现有投资,我会考虑512位SHA加SSL和Asp.Net的auth cookie足够 - 只要数据库真的安全(!)并且你没有SQL注入在网站上的洞。

For a BCrypt implementation of HashAlgorithm, see my answer to a similar question here . 对于HashAlgorithm的BCrypt实现,请参阅我在此处对类似问题的回答。

You would need to create a signed assembly with the sample code in my answer, and then modify your settings as needed: 您需要在我的答案中使用示例代码创建一个已签名的程序集,然后根据需要修改您的设置:

<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>

To be able to register a custom hashAlgorythmType, the first thing you need is a type that actually implements HashAlgorythm . 为了能够注册自定义hashAlgorythmType,您需要的第一件事是实际实现HashAlgorythm的类型。 If BCrypt implements it, it's your lucky day, but apparently it does NOT implement it, so this is your problem. 如果BCrypt实现它,那是你的幸运日,但显然它没有实现它,所以这是你的问题。

There is really no work around for it, as implementing HashAlgorithm is a requirement for being able to register it like this. 实际上没有解决方法,因为实现HashAlgorithm是能够像这样注册它的要求。

So what you are going to need to do is either write a wrapper around BCrypt to implement HashAlgorithm , or, of this is not possible, modify BCrypt itself to implement it. 所以你需要做的就是在BCrypt周围编写一个包装来实现HashAlgorithm ,或者,这是不可能的,修改BCrypt本身来实现它。

Unless you are really-really lucky and BCrypt is written in a way that easily lend itself to such a modification, it can require some non-trivial efforts. 除非你真的很幸运,并且BCrypt的编写方式很容易适应这种修改,否则它可能需要一些非常重要的努力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM