我已经使用 PHP函数crypt() 加密某些字符串。

的输出如下所示:

$1$Vf/.4.1.$CgCo33ebiHVuFhpwS.kMI0
$1$84..vD4.$Ps1PdaLWRoaiWDKCfjLyV1
$1$or1.RY4.$v3xo04v1yfB7JxDj1sC/J/

虽然相信隐窝()被使用MD5算法,则输出无效MD5哈希值。

是否有转换所产生的哈希值到有效MD5散列(16字节的十六进制值)?

的方式

更新

谢谢你的答复所以答案为止。我敢肯定,使用地穴功能是使用某种MD5算法的。什么我希望做的是转变,我有到一个MD5哈希,看起来像下面的输出中:

9e107d9d372bb6826bd81d3542a419d6  
e4d909c290d0fb1ca068ffaddf22cbd0  
d41d8cd98f00b204e9800998ecf8427e

(来自维基百科截取)

是否有从散列变换的一种方法,我必须的像以上?

有帮助吗?

解决方案

OK,也许这个答案是晚了一年,但我给它一个镜头。在你自己的答案,你注意到crypt()使用FreeBSD的MD5,这也确实对盐的一些有趣的转变运行哈希之前,所以就是我要给出的结果你将永远不会十分赞同的结果匹配调用md5()。您所看到的输出和你正在使用的格式之间的所述,唯一的区别是,你看到被编码为输出如下

$1$        # this indicates that it is MD5
Vf/.4.1.   # these eight characters are the significant portion of the salt
$          # this character is technically part of the salt, but it is ignored
CgCo33eb   # the last 22 characters are the actual hash
iHVuFhpw   # they are base64 encoded (to be printable) using crypt's alphabet
S.kMI0     # floor(22 * 6 / 8) = 16 (the length in bytes of a raw MD5 hash)

据我所知,通过隐窝使用的字母看起来是这样的:

./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

所以,这一切得紧一点,这里是你怎么能在22字符的隐窝的base64哈希值转换为32个字符的base16(十六进制)哈希:

首先,你需要的东西,以base64(自定义字母)转换成原16个字节的MD5哈希值。

define('CRYPT_ALPHA','./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
/**
 * Decodes a base64 string based on the alphabet set in constant CRYPT_ALPHA
 * Uses string functions rather than binary transformations, because said
 * transformations aren't really much faster in PHP
 * @params string $str  The string to decode
 * @return string       The raw output, which may include unprintable characters
 */
function base64_decode_ex($str) {
    // set up the array to feed numerical data using characters as keys
    $alpha = array_flip(str_split(CRYPT_ALPHA));
    // split the input into single-character (6 bit) chunks
    $bitArray = str_split($str);
    $decodedStr = '';
    foreach ($bitArray as &$bits) {
        if ($bits == '$') { // $ indicates the end of the string, to stop processing here
            break;
        }
        if (!isset($alpha[$bits])) { // if we encounter a character not in the alphabet
            return false;            // then break execution, the string is invalid
        }
        // decbin will only return significant digits, so use sprintf to pad to 6 bits
        $decodedStr .= sprintf('%06s', decbin($alpha[$bits]));
    }
    // there can be up to 6 unused bits at the end of a string, so discard them
    $decodedStr = substr($decodedStr, 0, strlen($decodedStr) - (strlen($decodedStr) % 8));
    $byteArray = str_split($decodedStr, 8);
    foreach ($byteArray as &$byte) {
        $byte = chr(bindec($byte));
    }
    return join($byteArray);
}

现在,你已经得到的原始数据,你需要一个方法,将其转换为你期待基16格式,再简单不过了。

/**
 * Takes an input in base 256 and encodes it to base 16 using the Hex alphabet
 * This function will not be commented.  For more info:
 * @see http://php.net/str-split
 * @see http://php.net/sprintf
 *
 * @param string $str   The value to convert
 * @return string       The base 16 rendering
 */
function base16_encode($str) {
    $byteArray = str_split($str);
    foreach ($byteArray as &$byte) {
        $byte = sprintf('%02x', ord($byte));
    }
    return join($byteArray);
}

最后,由于地下室的输出包括很多我们不需要(并且,事实上,不能使用),这个过程的数据,一个简短而亲切的功能,不仅会冻结这两个在一起,但允许直接从隐窝输出的输入。

/**
 * Takes a 22 byte crypt-base-64 hash and converts it to base 16
 * If the input is longer than 22 chars (e.g., the entire output of crypt()),
 * then this function will strip all but the last 22.  Fails if under 22 chars
 *
 * @param string $hash  The hash to convert
 * @param string        The equivalent base16 hash (therefore a number)
 */
function md5_b64tob16($hash) {
    if (strlen($hash) < 22) {
        return false;
    }
    if (strlen($hash) > 22) {
        $hash = substr($hash,-22);
    }
    return base16_encode(base64_decode_ex($hash));
}
鉴于这些功能

,你的三个例子的base16表示是:

3ac3b4145aa7b9387a46dd7c780c1850
6f80dba665e27749ae88f58eaef5fe84
ec5f74086ec3fab34957d3ef0f838154

当然,要记住,他们总是有效的,只是格式不同是很重要的。

其他提示

$ 1 $确实意味着这是一个MD5哈希,但隐窝生成随机盐。这就是为什么你会发现一个不同的MD5值。如果包括所生成的盐,你会发现同样的结果。

该盐base64编码在输出中,作为散列。

所使用的算法是一个系统范围的参数。一般来说,这是MD5,你是对的。

我相信答案我原来的问题是,不,你不能转换从一种格式到其他。

)由PHP隐窝(生成的哈希值似乎是由一个版本由波尔·亨宁·卡普创建FreeBSD的MD5哈希执行来生成。

http://people.freebsd.org/~phk/

从文档,这取决于系统。您可以强制通过设置参数盐使用的算法。从文档:

  

在加密类型是由触发   盐的说法。在安装时,   PHP决定的能力   crypt函数和接受盐   其它加密类型。如果没有盐   提供的是,PHP将自动生成   通过标准的两个字符盐   默认情况下,除非默认的加密   在系统上的类型是MD5,其中   区分随机MD5兼容盐是   生成。

http://php.net/crypt

  

隐窝()将使用标准的基于DES-Unix的加密算法或可选的算法可以是系统上可用的返回加密的字符串。

您想要的 md5() 功能:

  

计算使用»RSA数据安全公司MD5消息摘要算法str的MD5哈希,并返回该哈希值。结果   如果可选raw_output被设置为TRUE,则MD5摘要不是与16的长度返回原始二进制格式。   默认为false。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top