有人告诉我,他见过这样的软件系统:

从其他系统检索MD5加密密码; 解密加密的密码和 使用系统自己的算法将密码存储在系统的数据库中。

这可能吗?我认为解密MD5哈希是不可能/可行的。

我知道有MD5字典,但是有真正的解密算法吗?


当前回答

在寻找哈希函数的逆函数方面,没有办法“恢复”哈希函数。如前所述,这就是哈希函数的意义所在。它不应该是可逆的,它应该允许快速哈希值计算。因此,找到产生给定哈希值的输入字符串的唯一方法是尝试所有可能的组合。这就是所谓的蛮力攻击。

尝试所有可能的组合需要花费大量时间,这也是为什么使用哈希值以相对安全的方式存储密码的原因。如果攻击者能够访问您的数据库,其中包含所有用户密码,那么无论如何您都会失败。如果您有哈希值和(理想地说)强密码,那么攻击者将很难从哈希值中获取密码。

存储哈希值也没有性能问题,因为计算哈希值相对较快。因此,大多数系统所做的是计算用户输入的密码的哈希值(这很快),然后将其与用户数据库中存储的哈希值进行比较。

其他回答

MD5是一种哈希算法,不能还原哈希值。

您应该添加“更改密码功能”,用户提供另一个密码,计算散列并将其存储为新密码。

不,这是不可能的。您可以使用字典,也可以尝试散列不同的值,直到获得您正在寻找的散列。但它无法被“解密”。

在寻找哈希函数的逆函数方面,没有办法“恢复”哈希函数。如前所述,这就是哈希函数的意义所在。它不应该是可逆的,它应该允许快速哈希值计算。因此,找到产生给定哈希值的输入字符串的唯一方法是尝试所有可能的组合。这就是所谓的蛮力攻击。

尝试所有可能的组合需要花费大量时间,这也是为什么使用哈希值以相对安全的方式存储密码的原因。如果攻击者能够访问您的数据库,其中包含所有用户密码,那么无论如何您都会失败。如果您有哈希值和(理想地说)强密码,那么攻击者将很难从哈希值中获取密码。

存储哈希值也没有性能问题,因为计算哈希值相对较快。因此,大多数系统所做的是计算用户输入的密码的哈希值(这很快),然后将其与用户数据库中存储的哈希值进行比较。

不可能,至少在合理的时间内是不可能的。

通常的处理方式是密码“重置”。也就是说,你给他们一个新的(随机的)密码,并在电子邮件中发送给他们。

不,不可能反转诸如MD5这样的哈希函数:给定输出哈希值,除非已知关于输入消息的足够信息,否则不可能找到输入消息。

解密不是为哈希函数定义的函数;加密和解密是CBC模式下AES等密码的功能;哈希函数不加密也不解密。哈希函数用于摘要输入消息。顾名思义,没有反向算法可以设计。


MD5 has been designed as a cryptographically secure, one-way hash function. It is now easy to generate collisions for MD5 - even if a large part of the input message is pre-determined. So MD5 is officially broken and MD5 should not be considered a cryptographically secure hash anymore. It is however still impossible to find an input message that leads to a hash value: find X when only H(X) is known (and X doesn't have a pre-computed structure with at least one 128 byte block of precomputed data). There are no known pre-image attacks against MD5.

It is generally also possible to guess passwords using brute force or (augmented) dictionary attacks, to compare databases or to try and find password hashes in so called rainbow tables. If a match is found then it is computationally certain that the input has been found. Hash functions are also secure against collision attacks: finding X' so that H(X') = H(X) given H(X). So if an X is found it is computationally certain that it was indeed the input message. Otherwise you would have performed a collision attack after all. Rainbow tables can be used to speed up the attacks and there are specialized internet resources out there that will help you find a password given a specific hash.

It is of course possible to re-use the hash value H(X) to verify passwords that were generated on other systems. The only thing that the receiving system has to do is to store the result of a deterministic function F that takes H(X) as input. When X is given to the system then H(X) and therefore F can be recalculated and the results can be compared. In other words, it is not required to decrypt the hash value to just verify that a password is correct, and you can still store the hash as a different value.


重要的是使用密码哈希或PBKDF(基于密码的密钥派生函数)来代替MD5。这样的函数指定如何将盐和散列一起使用。这样就不会为相同的密码(来自其他用户或其他数据库)生成相同的散列。由于这个原因,密码哈希也不允许使用彩虹表,只要盐足够大并且正确随机。

Password hashes also contain a work factor (sometimes configured using an iteration count) that can significantly slow down attacks that try to find the password given the salt and hash value. This is important as the database with salts and hash values could be stolen. Finally, the password hash may also be memory-hard so that a significant amount of memory is required to calculate the hash. This makes it impossible to use special hardware (GPU's, ASIC's, FPGA's etc.) to allow an attacker to speed up the search. Other inputs or configuration options such as a pepper or the amount of parallelization may also be available to a password hash.

然而,它仍然允许任何人验证给定H(X)的密码,即使H(X)是密码哈希。密码哈希仍然是确定的,所以如果有人知道所有的输入和哈希算法本身,那么X可以用来计算H(X),并且-再说一次-结果可以进行比较。

常用的密码散列有bcrypt、scrypt和PBKDF2。还有各种形式的Argon2,它是最近密码哈希竞赛的赢家。在CrackStation上有一篇很好的关于密码安全的博文。


可以使对手无法执行哈希计算来验证密码是否正确。为此,可以使用胡椒作为密码散列的输入。或者,哈希值当然可以使用AES等密码和CBC或GCM等操作模式进行加密。然而,这需要独立存储秘密/密钥,并且比密码哈希有更高的访问要求。