首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用这个自定义散列函数,我是否遗漏了任何明显的安全缺陷?

使用这个自定义散列函数,我是否遗漏了任何明显的安全缺陷?
EN

Stack Overflow用户
提问于 2012-10-13 14:07:21
回答 2查看 898关注 0票数 3
代码语言:javascript
复制
<?php
function md7($text, $len)
{
  if($text)
  {
   $split = str_split(md5($text).md5(strlen($text)).md5($len), 5);
    foreach($split as $key=>$value)
    {
      $md5 = $md5.md5($value);
    }
    $split2 = str_split($md5);
    foreach($split2 as $kl=>$vl)
    {
      if($kl < $len)
      {
        $digest = $digest.$split2[$kl];
      }   
    }
    return $digest;
  }
} // end md7 function
?>

我创建这个函数是为了利用md5和可变长度的哈希,我相信这可以减少冲突的机会,我已经测试了MD5冲突的例子,它不会为这个函数创建冲突,我相信这个函数不会受到彩虹表的攻击。

EN

回答 2

Stack Overflow用户

发布于 2012-10-13 14:14:43

以下是一些明显的安全缺陷:

代码语言:javascript
复制
if($text)

"0"""都返回相同的散列。

代码语言:javascript
复制
foreach($split as $key=>$value)
{
  $md5 = $md5.md5($value);
}

您正在对第一个散列中的每个字母进行散列。对于$len <= 32,这将使您对md5($value)的第一个字母相同的所有字符串具有完全相同的散列值,本质上将熵从128位减少到4。以下是$len =32的所有16个散列值的完整列表:

代码语言:javascript
复制
8f14e45fceea167a5a36dedd4bea2543
92eb5ffee6ae2fec3ad71c777531578f
a87ff679a2f3e71d9181a67b7542122c
e4da3b7fbbce2345d7772b0674a318d5
c81e728d9d4c2f636f067f89cc14862c
8277e0910d750195b448797616e091ad
0cc175b9c0f1b6a831c399e269772661
45c48cce2e2d7fbdea1afc51c7c6ad26
4a8a08f09d37b73795649038408b5f33
e1671797c52e15f763380b45e841ec32
eccbc87e4b5ce2fe28308fd9f2a7baf3
c4ca4238a0b923820dcc509a6f75849b
8fa14cdd754f91cc6554c9e71929cce7
c9f0f895fb98ab9159f51fd0297e236d
1679091c5a880faf6fb5e6087eb1b2dc
cfcd208495d565ef66e7dff9f98764da

请注意,选择$len > 32并不能缓解此问题。您仍将只使用原始散列的第二个字母,这将使您的熵增加4位(现在最多为8位),这等于256个不同的散列。

我非常确定您需要32^32的长度才能与原始md5的熵相匹配。这是一个大得离谱的数字。

如果安全性是您想要的,那么就使用定义良好且经过良好测试的散列函数。PHP在hash函数中有一个sha1函数和许多其他函数。

散列函数通常由密码学社区创建和审查。它们比你能想到的几乎任何简单的hack都要好得多,所以不要实现你自己的散列函数,而要使用可用的散列函数。

票数 4
EN

Stack Overflow用户

发布于 2012-10-13 15:03:54

这里有一个问题可能值得考虑,但我没有办法轻松地分析md5散列。

让我们分两部分来考虑这一点,前半部分获取输入,对其进行哈希运算,并计算其长度和返回的长度。我不确定数组与字符串连接的效果是什么,但我将假定它只是为每个实例复制的。

然后遍历每个值并构建一个新值:$md5 = $md5.md5($value)。假设您返回的字符串最多为$len,这似乎是最大的缺点,因为您将从字符串中返回第一个$len字节。

有几个效果:$md5主要取决于输入的开头。试试像这样的东西

代码语言:javascript
复制
md7("aaaaaaaaaaaaaaaaaaaaaaaa", 16)
md7("aaaaaaaaaaaaaaaaaaaaaaab", 16)

看看你是否能得到类似的结果。我还没有尝试过这样做,但我的直觉是,您没有像您希望的那样正确地混合整个输入。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12870468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档