Eğer geçerli MD5 php crypt çıkış () dönüştürebilir miyim?

5 Cevap php

5 Cevap

Tamam, belki bu cevap bir yıl geç, ama ben bunu bir deneyeyim. Kendi cevap olarak, crypt() ayrıca karma çalıştırmadan önce tuz bazı ilginç dönüştürmeleri yapar FreeBSD MD5 kullanarak, unutmayın, bu yüzden seni asla oldukça vermek üzereyim ne sonuç Bir çağrı sonuçları ile maç md5(). O dedi, görüyoruz çıktı ve sizin için kullanılan biçimi arasındaki tek fark aşağıdaki gibi görüyoruz çıktı kodlanmış olmasıdır

$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)

Bildiğim kadarıyla, crypt tarafından kullanılan alfabe, bu gibi görünüyor:

./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Yani, akılda tüm bu ile, burada 32 karakter base16 (onaltılık) karma içine 22 karakter crypt-base64 hash dönüştürebilirsiniz nasıl:

İlk olarak, bir çiğ 16-bayt MD5 hash içine (özel alfabe ile) base64 dönüştürmek için bir şey gerekir.

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

Şimdi ham veri var ki, daha kolay olamazdı siz bekliyorsanız taban-16 formatında dönüştürmek için bir yöntem gerekir.

/**
 * 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);
}

Nihayet, mahzenin çıkış verilerinin çok ihtiyacımız yoktur (ve, aslında, kullanamazsınız) Bu işlem için, kısa ve tatlı bir işlevi bu ikisini bağlamak için değil, ancak çıkış doğrudan giriş için izin içerdiğinden mezarından.

/**
 * 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));
}

Bu işlevleri göz önüne alındığında, üç örnekten base16 temsilidir:

3ac3b4145aa7b9387a46dd7c780c1850
6f80dba665e27749ae88f58eaef5fe84
ec5f74086ec3fab34957d3ef0f838154

Tabii ki, her zaman sadece farklı biçimlendirilmiş, geçerli olduğunu hatırlamak önemlidir.

$ 1 $ gerçekten bu bir MD5 hash olduğu anlamına gelir, ama crypt rastgele bir tuz oluşturur. Farklı bir MD5 değeri bulmak nedeni budur. Eğer oluşturulan tuz eklerseniz aynı sonucu bulabilirsiniz.

Tuz karma olarak, çıkış base64 şifreli olduğunu.

Kullanılan algoritma, bir sistem geniş bir parametredir. Genellikle bu MD5, haklısın.

Benim asıl sorunun cevabı hayır, bir biçimden diğerine dönüştürmek olamaz inanıyorum.

Php crypt () tarafından oluşturulan sağlamalarının Poul-Henning Kamp tarafından oluşturulan FreeBSD MD5 hash uygulaması sürümü ile oluşturmak gibi görünmektedir.

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

Belgelere, bu sisteme bağlıdır. Sen tuz parametresini ayarlayarak kullanılan algoritma zorlayabilir. Dokümanlar:

The encryption type is triggered by the salt argument. At install time, PHP determines the capabilities of the crypt function and will accept salts for other encryption types. If no salt is provided, PHP will auto-generate a standard two character salt by default, unless the default encryption type on the system is MD5, in which case a random MD5-compatible salt is generated.