Domanda

Ho alcune stringhe che sono state crittografate utilizzando la funzione PHP crypt () .

Le uscite hanno un aspetto simile al seguente:

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

Mentre credo che crypt () stia usando l'algoritmo MD5, gli output non sono hash MD5 validi.

Esiste un modo per convertire gli hash prodotti in hash MD5 validi (valori esadecimali da 16 byte)?


Aggiornamento:

Grazie per le risposte così risposte finora. Sono abbastanza sicuro che la funzione crypt utilizzata stia usando una sorta di algoritmo MD5. Quello che sto cercando di fare è convertire l'output che ho in un hash MD5 simile al seguente:

9e107d9d372bb6826bd81d3542a419d6  
e4d909c290d0fb1ca068ffaddf22cbd0  
d41d8cd98f00b204e9800998ecf8427e

(tratto da Wikipedia )

Esiste un modo per convertire dagli hash che ho a quelli come sopra?

È stato utile?

Soluzione

OK, quindi forse questa risposta è in ritardo di un anno, ma ci proverò. Nella tua risposta, noti che crypt () sta usando FreeBSD MD5, che fa anche alcune interessanti trasformazioni sul sale prima di eseguire l'hash, quindi il risultato di quello che sto per darti non corrisponderà mai del tutto ai risultati di una chiamata a md5 () . Detto questo, l'unica differenza tra l'output che stai vedendo e il formato a cui sei abituato è che l'output che stai vedendo è codificato come segue

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

Per quanto ne so, l'alfabeto usato da cripta appare così:

./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Quindi, tenendo presente tutto ciò, ecco come è possibile convertire l'hash crypt-base64 a 22 caratteri in un hash base16 (esadecimale) a 32 caratteri:

Per prima cosa, hai bisogno di qualcosa per convertire il base64 (con alfabeto personalizzato) in un hash MD5 a 16 byte non elaborato.

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 == '

Ora che hai i dati grezzi, avrai bisogno di un metodo per convertirli nel formato base-16 che ti aspetti, il che non potrebbe essere più semplice.

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

Infine, poiché l'output di crypt include molti dati che non abbiamo bisogno (e, in effetti, non possiamo usare) per questo processo, una funzione breve e dolce non solo per legare questi due insieme ma per consentire input di output dalla cripta.

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

Date queste funzioni, la rappresentazione base16 dei tuoi tre esempi sono:

3ac3b4145aa7b9387a46dd7c780c1850
6f80dba665e27749ae88f58eaef5fe84
ec5f74086ec3fab34957d3ef0f838154

Naturalmente, è importante ricordare che erano sempre validi, formattati in modo diverso.

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

Ora che hai i dati grezzi, avrai bisogno di un metodo per convertirli nel formato base-16 che ti aspetti, il che non potrebbe essere più semplice.

<*>

Infine, poiché l'output di crypt include molti dati che non abbiamo bisogno (e, in effetti, non possiamo usare) per questo processo, una funzione breve e dolce non solo per legare questi due insieme ma per consentire input di output dalla cripta.

<*>

Date queste funzioni, la rappresentazione base16 dei tuoi tre esempi sono:

<*>

Naturalmente, è importante ricordare che erano sempre validi, formattati in modo diverso.

Altri suggerimenti

$ 1 $ significa infatti che si tratta di un hash MD5, ma crypt genera un salt casuale. Ecco perché trovi un valore MD5 diverso. Se includi il sale generato troverai lo stesso risultato.

Il salt è codificato in base64 nell'output, come l'hash.

L'algoritmo utilizzato è un parametro di sistema. Generalmente questo è MD5, hai ragione.

Credo che la risposta alla mia domanda originale sia no, non puoi convertire da un formato all'altro.

Gli hash generati da php crypt () sembrano essere generati da una versione dell'implementazione di hash MD5 di FreeBSD creata da Poul-Henning Kamp.

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

Dalla documentazione, questo dipende dal sistema. È possibile forzare l'algoritmo utilizzato impostando il parametro salt. Dai documenti:

  

Il tipo di crittografia è attivato da   l'argomento sale. Al momento dell'installazione,   PHP determina le capacità di   funzione di cripta e accetterà sali   per altri tipi di crittografia. Se non sale   viene fornito, PHP genererà automaticamente a   sale standard a due caratteri di   impostazione predefinita, a meno che la crittografia predefinita   digitare sul sistema è MD5, in cui   nel caso in cui un sale casuale compatibile con MD5 sia   generato.

Da http://php.net/crypt :

  

crypt () restituirà una stringa crittografata usando l'algoritmo di crittografia standard basato su DES Unix o algoritmi alternativi che potrebbero essere disponibili sul sistema.

Desideri la md5 () :

  

Calcola l'hash MD5 di str usando & # 187; RSA Data Security, Inc. MD5 Message-Digest Algorithm e restituisce l'hash.
  Se raw_output opzionale è impostato su TRUE, il digest md5 viene invece restituito in formato binario non elaborato con una lunghezza di 16.   L'impostazione predefinita è FALSO.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top