使用 MD5 或 sha-256 C# 对密码进行哈希处理
我正在为应用程序编写注册表单,但对于 C# 新手来说仍然存在问题。
我希望将密码加密/哈希为 md5 或 sha-256,最好是 sha-256。
有什么好的例子吗?我希望它能够从“字符串密码;”中获取信息然后对其进行散列并存储在变量“string hPassword;”中。有什么想法吗?
I'm writing a register form for a application but still having problems with being new to c#.
I am looking to encrypt/hash passwords to md5 or sha-256, preferably sha-256.
Any good examples? I want it to be able to take the information from "string password;" and then hash it and store in the variable "string hPassword;". Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
不要使用简单的哈希,甚至是加盐的哈希。使用某种密钥强化技术,例如 bcrypt (带有 .NET 实现)或 PBKDF2(带有 内置实现)。
这是使用 PBKDF2 的示例。
从您的密码生成密钥...
然后测试密码是否有效...
Don't use a simple hash, or even a salted hash. Use some sort of key-strengthening technique like bcrypt (with a .NET implementation here) or PBKDF2 (with a built-in implementation).
Here's an example using PBKDF2.
To generate a key from your password...
And then to test if a password is valid...
您将需要使用
System.Security .Cryptography
命名空间;具体来说,MD5
类< /a> 或SHA256
类。从此页面上的代码中提取一些内容,以及知道两个类具有相同的基类(
HashAlgorithm
),您可以使用这样的函数:然后您可以这样调用它(对于 MD5):
或者对于 SHA256:
编辑:添加盐支持
正如 dtb 在评论中指出的那样,如果这段代码能够添加 salt< /a>.如果您不熟悉它,盐是一组随机位,它们作为散列函数的输入包含在内,这对于阻止针对散列密码的字典攻击有很大帮助(例如,使用 彩虹表)。这是支持 salt 的
ComputeHash
函数的修改版本:希望这对您有所帮助!
You're going to want to use the
System.Security.Cryptography
namespace; specifically, theMD5
class or theSHA256
class.Drawing a bit from the code on this page, and with the knowledge that both classes have the same base class (
HashAlgorithm
), you could use a function like this:Then you could call it like this (for MD5):
Or for SHA256:
Edit: Adding Salt Support
As dtb pointed out in the comments, this code would be stronger if it included the ability to add salt. If you're not familiar with it, salt is a set of random bits that are included as an input to the hashing function, which goes a long way to thwart dictionary attacks against a hashed password (e.g., using a rainbow table). Here's a modified version of the
ComputeHash
function that supports salt:Hope this has been helpful!
将密码存储在数据库中时,应始终在散列之前对其进行加盐。
推荐的数据库列:
您在网上找到的大多数帖子都会讨论 ASCII 编码盐和散列,但这是不需要的,只会增加不需要的计算。另外,如果您使用SHA-1,那么输出将只有 20 个字节,因此数据库中的哈希字段长度只需 20 个字节。我理解您询问 SHA-256,但除非您有令人信服的理由,否则在大多数业务实践中使用具有盐值的 SHA-1 就足够了。如果您坚持使用 SHA-256,那么数据库中的哈希字段长度需要为 32 字节。
下面是一些函数,它们将生成盐、计算哈希值并根据密码验证哈希值。
下面的 salt 函数根据 4 个以加密方式创建的随机字节生成一个整数形式的加密强盐。
然后可以使用盐和以下函数对密码进行哈希处理。将盐与密码连接起来,然后计算哈希值。
检查密码只需计算哈希值,然后将其与预期哈希值进行比较即可完成。
You should always salt the password before hashing when storing them in the database.
Recommended database columns:
Most posts you find online will talk about ASCII encoding the salt and hash, but that is not needed and only add unneeded computation. Also if you use SHA-1, then the output will only be 20 bytes so your hash field in the database only needs to be 20 bytes in length. I understand your asking about SHA-256, but unless you have a compelling reason, using SHA-1 with a salt value will be sufficient in most business practices. If you insist on SHA-256, then the hash field in the database needs to be 32 bytes in length.
Below are a few functions that will generate the salt, compute the hash and verify the hash against a password.
The salt function below generates a cryptographically strong salt as an Integer from 4 cryptographically created random bytes.
The password can then be hashed using the salt with the function below. The salt is concatenated to the password and then the hash is computed.
Checking the password can be done simply by computing the hash and then comparing it to the expected hash.
TL;DR 使用 Microsoft.AspNetCore .Cryptography.KeyDerivation,使用 SHA-512 实现 PBKDF2。
开始使用密码哈希的好主意是查看 OWASP 指南的内容。推荐的算法列表包括 Argon2、PBKDF2、scrypt 和 bcrypt。所有这些算法都可以调整,以调整哈希密码所需的时间,以及相应地通过暴力破解密码的时间。所有这些算法都利用盐来防止彩虹表攻击。
这两种算法都不是很弱,但有一些区别:
经受住了时间的考验。它对 GPU 有很强的抵抗力
。
功能。它不提供针对 GPU 或 ASIC 攻击的特定保护,特别是在使用 SHA-1 等较弱的哈希函数时,但如果它对您很重要,则它经过 FIPS 认证,并且如果迭代次数为足够大。
仅基于算法,我可能会选择 bcrypt,PBKDF2 是最不受欢迎的。
然而,这并不是故事的全部,因为即使是最好的算法也可能因为糟糕的实现而变得不安全。让我们看看 .NET 平台可用的内容:
著名的 libsodium 库,例如
https://github.com/adamcaudill/libsodium-net。这个想法是
大部分加密货币是通过 libsodium 实现的,它具有相当大的
支持,并且“未经测试”的部分非常有限。然而,在
密码学细节意义重大,因此与 Argon2 结合起来
相对较新,我将其视为实验性选项
Rfc2898DeriveBytes 类。然而,实现上只能使用SHA-1哈希函数,现在看来速度太快,不安全
Microsoft.AspNetCore.Cryptography.KeyDerivation 包
可通过 NuGet 获取。它提供带有 SHA-1、SHA-256 或 SHA-512 哈希函数的 PBKDF2 算法,这比
Rfc2898DeriveBytes
好得多。这里最大的优势是该实现是由 Microsoft 提供的,虽然我无法正确评估 Microsoft 开发人员与 BCrypt.net 或 libsodium 开发人员的加密勤奋,但信任它是有意义的,因为如果您正在运行 .NET 应用程序,已经严重依赖微软了。如果发现安全问题,我们也可能期望微软发布更新。希望如此。总结到目前为止的研究,虽然 PBKDF2 可能是四种算法中最不受欢迎的算法,但 Microsoft 提供的实现的可用性胜过这一点,因此合理的决定是使用 Microsoft.AspNetCore.Cryptography.KeyDerivation< /代码>。
目前最新的包面向 .NET Standard 2.0,因此可在 .NET Core 2.0 或 .NET Framework 4.6.1 或更高版本中使用。如果您使用早期的框架版本,则可以使用以前版本的包, 1.1.3,面向 .NET Framework 4.5.1 或 .NET Core 1.0。不幸的是,甚至无法在 .NET 的早期版本中使用它。
文档和工作示例位于 learn.microsoft.com。但是,不要按原样复制粘贴,开发人员仍然需要做出决定。
第一个决定是使用什么哈希函数。可用选项包括 SHA-1、SHA-256 和 SHA-512。其中,SHA-1 绝对太快而无法保证安全,SHA-256 还不错,但我会推荐 SHA-512,因为据说它的 64 位操作使用使得更难从基于 GPU 的攻击中受益。
然后,您需要选择密码哈希输出长度和盐长度。输出长于哈希函数输出(例如 SHA-512 的 512 位)是没有意义的,并且完全像这样可能是最安全的。对于盐的长度,意见不一。 128 位应该足够了,但无论如何,长度超过哈希输出长度肯定不会带来任何好处。
接下来是迭代计数。它越大,密码哈希就越难破解,但用户登录所需的时间就越长。我建议选择它,这样哈希在典型的生产系统上需要 0.25 - 1 秒,并且在任何情况下,它不应小于 10000。
通常,您会得到字节数组作为盐和哈希值。使用 Base64 将它们转换为字符串。您可以选择在数据库中使用两个不同的列,或者使用 Base64 中未遇到的分隔符将盐和密码合并在一列中。
不要忘记设计密码散列存储,以便将来无缝地转向更好的散列算法。
TL;DR use Microsoft.AspNetCore.Cryptography.KeyDerivation, implementing PBKDF2 with SHA-512.
The good idea to get started with password hashing is to look at what OWASP guidelines say. The list of recommended algorithms includes Argon2, PBKDF2, scrypt, and bcrypt. All these algorithms can be tuned to adjust the time it takes to hash a password, and, correspondingly, the time to crack it via brute-force. All these algorithms utilize salt to protect from rainbow tables attacks.
Neither of these algorithms is terribly weak, but there are some differences:
has withstood the test of time. It is pretty resistant to GPU
attacks, but not to FPGA
functions. It does not offer a specific protection against GPU or ASIC attacks, especially if a weaker hash function like SHA-1 is used, but it is, however, FIPS-certified if it matters to you, and still acceptable if the number of iterations is large enough.
Based on algorithms alone, I would probably go with bcrypt, PBKDF2 being the least favorable.
However, it's not the full story, because even the best algorithm can be made insecure by a bad implementation. Let's look at what is available for .NET platform:
well-known libsodium library, e.g.
https://github.com/adamcaudill/libsodium-net. The idea is that
the most of the crypto is implemented via libsodium, which has considerable
support, and the 'untested' parts are pretty limited. However, in
cryptography details mean a lot, so combined with Argon2 being
relatively recent, I'd treat it as an experimental option
Rfc2898DeriveBytes class. However, the implementation can only use SHA-1 hash function, which is deemed too fast to be secure nowadays
Microsoft.AspNetCore.Cryptography.KeyDerivation package
available via NuGet. It provides PBKDF2 algorithm with SHA-1, SHA-256, or SHA-512 hash functions, which is considerably better than
Rfc2898DeriveBytes
. The biggest advantage here is that the implementation is supplied by Microsoft, and while I cannot properly assess cryptographic diligence of Microsoft developers versus BCrypt.net or libsodium developers, it just makes sense to trust it because if you are running a .NET application, you are heavily relying on Microsoft already. We might also expect Microsoft to release updates if security issues are found. Hopefully.To summarize the research up to this point, while PBKDF2 might be the least preferred algorithm of the four, the availability of Microsoft-supplied implementation trumps that, so the reasonable decision would be to use
Microsoft.AspNetCore.Cryptography.KeyDerivation
.The recent package at the moment targets .NET Standard 2.0, so available in .NET Core 2.0 or .NET Framework 4.6.1 or later. If you use earlier framework version, it is possible to use the previous version of the package, 1.1.3, which targets .NET Framework 4.5.1 or .NET Core 1.0. Unfortunately, it is not possible to use it in even earlier versions of .NET.
The documentation and the working example is available at learn.microsoft.com. However, do not copy-paste it as it is, there are still decisions a developer needs to make.
The first decision is what hash function to use. Available options include SHA-1, SHA-256, and SHA-512. Of those, SHA-1 is definitely too fast to be secure, SHA-256 is decent, but I would recommend SHA-512, because supposedly, its 64-bit operations usage makes it harder to benefit from GPU-based attacks.
Then, you need to choose the password hash output length and the salt length. It doesn't make sense to have output longer than the hash function output (e.g. 512 bits for SHA-512), and it would probably be the most secure to have it exactly like that. For the salt length, opinions differ. 128 bits should be enough, but in any case, the length longer than the hash output length surely doesn't provide any benefits.
Next, there is an iteration count. The bigger it is, the harder password hashes are to crack, but the longer it takes to log users in. I'd suggest to choose it so the hashing takes 0.25 - 1 seconds on the typical production system, and in any case, it should not be less than 10000.
Normally, you would get bytes array as salt and hash values. Use Base64 to convert them to strings. You can opt to use two different columns in the database, or combine salt and password in one column using a separator which is not encountered in Base64.
Don't forget to devise a password hashing storage in a way that allows to seamlessly move to a better hashing algorithm in future.
如果您要存储哈希密码,请使用 bcrypt 而不是 SHA-256。问题在于 SHA-256 针对速度进行了优化,如果有人访问您的数据库,则更容易对密码进行暴力攻击。
阅读这篇文章:彩虹表已经足够了:关于安全密码方案您需要了解的内容和这个回答之前的问题。
文章中的一些引用:
If you are going to be storing the hashed passwords, use bcrypt instead of SHA-256. The problem is that SHA-256 is optimized for speed, which makes it easier for a brute force attack on passwords should someone get access to your database.
Read this article: Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes and this answer to a previous SO question.
Some quotes from the article:
PBKDF2 使用 HMACSHA1.......如果您想要更现代的 HMACSHA256 或 HMACSHA512 实现,并且仍然希望密钥拉伸以使算法变慢,我建议使用此 API:https://sourceforge.net/projects/pwdtknet/
PBKDF2 is using HMACSHA1.......if you want more modern HMACSHA256 or HMACSHA512 implementation and still want key stretching to make the algorithm slower I suggest this API: https://sourceforge.net/projects/pwdtknet/
这是持久性不知道的 SecuredPassword 类的完整实现
和测试:
Here is a full implementation of a persistence unaware SecuredPassword class
And tests:
System.Security.Cryptography.SHA256 类应该可以解决问题:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256.aspx
The System.Security.Cryptography.SHA256 class should do the trick:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256.aspx
请使用这个,因为我之前也遇到过同样的问题,但可以通过小代码片段解决它
Please use this as i have the same issues before but could solve it will the litle code snippet