문제

다음을 사용하여 암호화된 일부 문자열이 있습니다. PHP 함수 crypt().

출력은 다음과 같습니다.

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

나는 crypt()가 MD5 알고리즘을 사용하고 있다고 생각하지만 출력은 유효한 MD5 해시가 아닙니다.

생성된 해시를 유효한 MD5 해시(16바이트 16진수 값)로 변환하는 방법이 있습니까?


업데이트:

지금까지 답변을 주셔서 감사합니다.나는 사용된 암호화 기능이 일종의 MD5 알고리즘을 사용하고 있다고 확신합니다.내가 하려는 것은 내가 가지고 있는 출력을 다음과 같은 MD5 해시로 변환하는 것입니다.

9e107d9d372bb6826bd81d3542a419d6  
e4d909c290d0fb1ca068ffaddf22cbd0  
d41d8cd98f00b204e9800998ecf8427e

(에서 가져옴 위키피디아)

내가 가지고 있는 해시를 위와 같은 해시로 변환하는 방법이 있나요?

도움이 되었습니까?

해결책

좋아, 아마도이 대답은 1 년 늦었을 것입니다. 그러나 나는 그것을 한 번 줄 것입니다. 자신의 대답으로, 당신은 그것을 주목합니다 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)

내가 아는 한, Crypt에서 사용하는 알파벳은 다음과 같습니다.

./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

따라서이 모든 것이 염두에두고 22 자 Crypt-Base64 해시를 32 문자 Base16 (16 진수) 해시로 변환 할 수있는 방법은 다음과 같습니다.

먼저 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);
}

원시 데이터가 생겼으므로 예상하는 Base-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);
}

마지막으로, Crypt의 출력에는이 프로세스에 필요하지 않은 많은 데이터가 포함되어 있으므로이 두 가지를 함께 묶을뿐만 아니라 출력의 직접 입력을 허용하는 짧고 달콤한 기능입니다. Crypt에서.

/**
 * 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 해시임을 의미하지만 crypt는 임의의 솔트를 생성합니다.이것이 다른 MD5 값을 찾는 이유입니다.생성된 소금을 포함하면 동일한 결과를 얻을 수 있습니다.

솔트는 출력에서 ​​해시로 base64로 인코딩됩니다.

사용된 알고리즘은 시스템 전체 매개변수입니다.일반적으로 이것은 MD5입니다. 당신 말이 맞습니다.

나는 원래 질문에 대한 대답이 아니오라고 생각합니다. 한 형식에서 다른 형식으로 변환 할 수 없습니다.

PHP Crypt ()에 의해 생성 된 해시는 Poul-Henning Kamp가 작성한 FreeBSD MD5 해시 구현의 버전에 의해 생성되는 것으로 보입니다.

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

문서에서 이것은 시스템에 따라 다릅니다. 소금 매개 변수를 설정하여 사용 된 알고리즘을 강제로 강제 할 수 있습니다. 문서에서 :

암호화 유형은 소금 인수에 의해 트리거됩니다. 설치 시간에 PHP는 Crypt 기능의 기능을 결정하고 다른 암호화 유형에 대한 소금을 수용합니다. 소금이 제공되지 않으면 시스템의 기본 암호화 유형이 MD5가 아닌 한 PHP는 기본적으로 표준 2 문자 염을 자동 생성합니다.

에서 http://php.net/crypt:

Crypt ()는 표준 UNIX DES 기반 암호화 알고리즘 또는 시스템에서 사용할 수있는 대체 알고리즘을 사용하여 암호화 된 문자열을 반환합니다.

당신은 원합니다 md5() 기능:

»RSA Data Security, Inc. MD5 Message Ingest 알고리즘을 사용하여 STR의 MD5 해시를 계산하고 해시를 반환합니다.
옵션 RAW_OUTPUT가 True로 설정되면 MD5 다이제스트는 길이가 16 인 원시 바이너리 형식으로 반환됩니다. 기본값은 false입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top