如何创建md5哈希作为crypt函数使用md5函数生成md5盐,而不是crypt函数?

时间:2011-02-15 06:12:04

标签: php encryption md5 salt crypt

我更喜欢在php中使用crypt函数来进行密码加密和其他单向加密要求。因为我可以使用任何支持的加密算法,通过更改盐并没有其他几个优点。通常情况下,我不使用任何盐,它需要随机的MD5盐。我将此加密字符串保存为数据库中的密码哈希,并在对用户进行身份验证时,将其用作crypt函数的salt。它在PHP中工作正常。但是当需要任何其他编程语言来创建哈希时,虽然我在函数的php部分使用了crypt函数,但我们遇到了问题。

我想知道是否有任何简单的方法来创建MD5哈希(使用PHP md5()函数或其他),这需要与使用MD5盐时crypt函数生成的类似。如果我能理解它在php中是如何工作的,而不使用crypt函数,那么可能很有可能在其他编程语言中实现。

1 个答案:

答案 0 :(得分:0)

这是实现相同功能的code in Java。这可以帮助您在其他语言中执行相同操作。

对于PHP,您可能需要查看以下代码:

    echo 'MD5:          ' . crypt('mypassword', '$1$somesalt$') . "\n";
    echo 'MD5:          ' . mycrypt('mypassword', 'somesalt') . "\n";

    function to64($s, $n)
    {
        $i64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        $r = '';
        while (--$n >= 0) {
            $ss = $s & 0x3f;
            $r .= $i64[$s & 0x3f];
            $s >>= 6;
         }
        return $r;
    }

    function mycrypt($v, $s) {
            $m = hash_init("md5");
            hash_update($m, $v);
            hash_update($m, '$1$');
            hash_update($m, $s);

            $m1 = hash_init("md5");
            hash_update($m1, $v);
            hash_update($m1, $s);
            hash_update($m1, $v);
            $final = hash_final($m1, true);
            for ($pl = strlen($v); $pl>0; $pl-=16) {
                    hash_update($m, substr($final, 0, $pl > 16? 16:$pl));
            }
            $final = "\0";
            for($i=strlen($v);$i!=0;$i>>=1) {
                    if (($i & 1) != 0) {
                            hash_update($m, $final);
                    } else {
                            hash_update($m, $v[0]);
                   }
            }
            $final = hash_final($m, true);
            for($i=0;$i<1000;$i++) {
                $m1 = hash_init("md5");

                if(($i&1)) {
                    hash_update($m1, $v);
                } else {
                    hash_update($m1, $final);
                }
                if(($i%3)) {
                    hash_update($m1, $s);
                }
                if(($i%7)) {
                    hash_update($m1, $v);
                }
                if(($i&1)) {
                    hash_update($m1, $final);
                } else {
                    hash_update($m1, $v);
                }
                $final = hash_final($m1, true);
            }
            $l = '$1$'.$s.'$';
            $l .= to64(ord($final[ 0])<<16 | (ord($final[ 6])<<8) | ord($final[12]), 4);
            $l .= to64(ord($final[ 1])<<16 | (ord($final[ 7])<<8) | ord($final[13]), 4);
            $l .= to64(ord($final[ 2])<<16 | (ord($final[ 8])<<8) | ord($final[14]), 4);
            $l .= to64(ord($final[ 3])<<16 | (ord($final[ 9])<<8) | ord($final[15]), 4);
            $l .= to64(ord($final[ 4])<<16 | (ord($final[10])<<8) | ord($final[ 5]), 4);
            $l .= to64(ord($final[11]), 2);

            return $l;
    }