在 $a == md5($b . $secret) 中查找 $secret
函数是:
$a == md5($b . $secret);
- 您可以选择 $a 和 $b
- 您不知道 $secret
- 您将获得您选择的 $a 和 $b 的函数值(true 或 false)。
一般来说,有没有比暴力破解更好的攻击来找到 $secret 呢? 有没有比使用 PHP 的 md5 函数 暴力破解更好的攻击?
从我在网上发现的情况来看,我认为没有,尽管 md5 在其他一些用例中已被弃用。所以只是为了确定......
亲切的问候
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果 MD5 的行为就像一个随机预言(这是一个很大的“如果”,见下文),那么对
$secret
的详尽搜索就是最好的攻击——更重要的是,对 $secret 的每个“猜测”$secret
的值必须使用对该函数的查询(因为您使用 PHP,我假设该函数是在 Web 服务器中实现的,并且每个“查询”都需要与该服务器通信)。后者是由于缺乏发送回攻击者的信息而暗示的:攻击者除了单个位(“True
”或“False
”结果)之外什么也得不到。 。特别是,他没有得到 MD5 输出本身。攻击者将获得一长串无信息的“False
”结果,除非他命中正确的 MD5 输出,无论是出于纯粹的偶然(概率 2-128,这真是该死的)小),或者因为他事先正确猜测了$secret
的值。值得注意的是,这可以防止攻击者使用许多成本分摊技术,包括预先计算的表,特别是过度炒作的 彩虹表。随机预言是一个神话对象,可以被视为确定性的黑匣子:你知道<从给定的输入中您将得到什么输出,除了该框将始终为给定的输入返回相同的结果。模型如下:盒子里有一个侏儒、一些骰子和一本大书。侏儒使用骰子来随机选择输出。他还使用这本书来跟踪他已经发送的答案,以便保持一致,即如果输入与之前提交的输入相同,则侏儒将返回与之前相同的输出,而不是扔骰子。
然而,MD5 并不是随机预言。例如,对于具有 128 位输出的函数,我们可以比理论上的 264 阻力更快地构建 MD5 碰撞。另外,请注意,成为一个好的哈希函数(抗冲突等)并不绝对需要“随机预言”。例如,SHA-256 被认为是安全哈希函数,但它仍然遭受所谓的“长度扩展攻击”(给定
SHA256($a)
,人们可以在不知道$ 的情况下计算
,对于SHA256($a . $b)
a$b
的几乎任意值)。因此,MD5(或 SHA-256)并不保证随机预言。这并不意味着更快的攻击是已知的!只是你在这里只能靠自己。还可以指出
md5($b . $secret)
是一种“密钥哈希”,即 MAC(消息验证码)。从哈希函数构建 MAC 并不容易,正是因为诸如长度扩展攻击之类的事情(例如,md5($secret . $b)
,这将是一个非常糟糕的 MAC)。一种用哈希函数构建 MAC 的稳健方法已经被设计出来;它被称为 HMAC 并涉及底层哈希函数的两次调用(但其中之一是在一个短输入上,所以这仍然是有效的)。 HMAC 的安全性,更准确地说,HMAC 如何被视为随机预言机,可以被“证明”,即简化为一些哈希函数内部属性,这些属性在 SHA-256 的情况下被认为是正确的(参见 NMAC 和 HMAC 的新证明:无抗碰撞的安全性,作者:Mihir Bellare,了解详细信息)。通过在$b
上使用 HMAC/SHA-256,以$secret
作为密钥,您将从这些安全结果中受益,并且您的构造将更加可靠。再说一次,我并不是说存在对md5($b . $secret)
的已知攻击,只是使用 MD5 和自制的 MAC 构造都会提高危险信号,会降低对此类系统的信任程度。If MD5 behaves like a random oracle (that's a big "if", see below), then exhaustive search on
$secret
is the best possible attack -- and, more importantly, each "guess" on the value of$secret
MUST use a query to the function (since you use PHP, I assume that the function is implemented in a Web server, and each "query" requires talking to that server). The latter is implied by the lack of information sent back to the attacker: the attacker does not get anything except a single bit (the "True
" or "False
" result). In particular, he does not get the MD5 output itself. The attacker will get a long stream of uninformative "False
" results unless he hits the correct MD5 output, either out of pure chance (probability 2-128, which is Really Darn Small), or because he properly guessed the value of$secret
beforehand. It is worth noticing that this prevents the attacker from using many cost-sharing techniques, including precomputed tables, in particular the over-hyped rainbow tables.A random oracle is a mythical object which can be viewed as a deterministic black box: you know nothing on the output you will get from a given input, except that the box will always return the same result for a given input. A model is the following: the box contains a gnome, some dice and a big book. The gnome uses the dice to randomly choose the output. He also uses the book to keep track of the answers he already sent, so as to be consistent, i.e. if the input is identical to a previously submitted input, the gnome will return the same output than previously instead of throwing dice.
MD5, however, is not a random oracle. For instance, we can build collisions for MD5 much faster than the theoretical 264 resistance for a function with a 128-bit output. Also, note that being a good hash function (collision-resistant and so on) does not absolutely require "random-oracleness". For instance, SHA-256 is considered to be a secure hash function, while it still suffers from the so-called "length extension attack" (given
SHA256($a)
, one can computeSHA256($a . $b)
without knowing$a
, for almost arbitrary values of$b
). So the guarantees of a random oracle do not hold with MD5 (or, for that matter, SHA-256). This does not mean that faster attacks are known ! Only that you are on your own here.One can also point out that
md5($b . $secret)
is a kind of "keyed hash", i.e. a MAC (Message Authentication Code). Building a MAC out of a hash function is not easy, precisely because of things like the length extension attack (md5($secret . $b)
, for instance, would be a very poor MAC). A robust way of building a MAC out of a hash function has been designed; it is called HMAC and involves two invocations of the underlying hash function (but one of them is on a short input, so this is efficient nonetheless). Security of HMAC, more precisely how HMAC can be considered to behave as a random oracle, can be "proven", i.e. reduced to some hash function internal properties which are believed true in the case of SHA-256 (see New Proofs for NMAC and HMAC: Security without Collision-Resistance by Mihir Bellare for the gory details). By using HMAC/SHA-256 over$b
, with$secret
as key, you would benefit from these security results, and your construction would be more convincingly robust. Then again, I do not claim that there is a known attack onmd5($b . $secret)
, only that both the use of MD5 and the homemade MAC construction raise red flags, which degrade the level of trust which can be imparted to such a system.这是一个有趣的问题,因为在 IT 安全的典型场景中,您不能选择
$a
和$b
作为攻击者。例如,如果您能够获得哈希密码,则$a
和$b
已定义,您必须使用它们。在这种情况下,如果有盐$b
可用,您只能使用暴力破解或彩虹表。另一方面,在您的示例中,您可以自由选择这两个值。您可以采用任意秘密,例如
test
并相应地选择$a
和$b
的值。我选择 $b 作为空字符串
,并使用$a = md5($secret)
计算$a
,结果为098f6bcd4621d373cade4e832627b4f6。
我选择
$a = "098f6bcd4621d373cade4e832627b4f6"
和$b= ""
并询问您是否$secret == "test"
。你说是真的,我说问题解决了。这最终引导我们找到真正的答案。给定的两个条件
不能一起工作。在我的示例中,我自己定义了
$secret
。我违反了第二个条件。另一方面,我不能在不从$secret
派生的情况下任意选择$a
和$b
,因为它们可能没有解决方案。如果我们假设所有可能的
$a
和$b
对至少有一个解决方案(也许有证据证明这一点,我不知道),并且你以一种你真的不知道$secret
的方式选择它们,我总是想定义$b = ""
,以使攻击尽可能简单。在这种情况下,彩虹桌就是你的朋友。This is an interesting question, because in the typical scenarios in IT-Security you cannot choose
$a
and$b
as an attacker. If you are able to get hold of a hashed password for example,$a
and$b
are already defined and you have to work with that. In that case you can only use brute-force or a rainbow table if one with the salt$b
is available.In your example on the other hand, you are free to choose both values. You can take an arbitrary secret, e.g.
test
and choose the values for$a
and$b
accordingly. I choose $b to be anempty string
and calculate$a
with$a = md5($secret)
, which results in098f6bcd4621d373cade4e832627b4f6
.I choose
$a = "098f6bcd4621d373cade4e832627b4f6"
and$b= ""
and ask you if$secret == "test"
. You say true and I say problem solved.This finally leads us to the real answer. The two conditions given
do not work together. In my example I defined
$secret
myself. I violated the second condition. On the other hand I cannot choose$a
and$b
arbitrarily without deriving them from$secret
, because they might not have a solution.If we assume that there is at least one solution for all possible pairs of
$a
and$b
(maybe there is proof for that, I don't know), and you select them in a way that you really do not know$secret
, I would always want to define$b = ""
, to make the attack as easy as possible. Rainbow tables are your friends in that case.下载著名密码的彩虹表/密码哈希! :)
download a rainbow table / password hash of famous password ! :)