SSHA è un SHA-1 salato. Per impostazione predefinita, gli ultimi 4 byte sono il sale. L'output di slappasswd è
'{<Hash Method>}<base64 converted hash and salt>'
Pertanto, per verificare se una password in testo normale è uguale alla SHA salata, è necessario:
- eliminare lo specificatore del metodo hash con es. sed.
- decodifica la stringa base64
- estrarre gli ultimi 4 byte, questo è il sale
- concatenare il sale con la password del testo normale
- l'ha fatto
- confrontare
La stringa decodificata base64 contiene l'hash in forma binaria e non può essere stampata, quindi la convertiremo in esadecimale con od. I primi 3 passaggi vengono eseguiti con il seguente codice:
#!/bin/bash
output=$(slappasswd -h {SSHA} -s password)
hashsalt=$( echo -n $output | sed 's/{SSHA}//' | base64 -d)
salt=${hashsalt:(-1),(-4)}
echo $output
echo $(echo -n $hashsalt | od -A n -t x1)
echo "Salt: $salt"
L'output potrebbe essere:
{SSHA}fDu0PgKDn1Di9W1HMINpPXRqQ9jTYjuH
7c 3b b4 3e 02 83 9f 50 e2 f5 6d 47 30 83 69 3d 74 6a 43 d8 d3 62 3b 87
<------------------------- Hash --------------------------> <-- Salt-->
Salt: ▒b;▒
Quindi ora dobbiamo concatenare il sale con la password in chiaro e l'hash, questa volta senza salare! Il problema che ho avuto è stato capire che il sale può davvero essere qualsiasi personaggio, compresi i caratteri non stampabili. Per concatenare questi caratteri non stampabili useremo printf e le loro rappresentazioni esadecimali:
slappasswd -h {SHA} -s $(printf 'password\xd3\x62\x3b\x87') | sed 's/{SHA}//' | base64 -d | od -A n -t x1
L'output è:
7c 3b b4 3e 02 83 9f 50 e2 f5 6d 47 30 83 69 3d 74 6a 43 d8
Che è uguale all'hash sopra. Ora abbiamo verificato che la 'password' corrisponde allo SHA salato.
Grazie e ulteriori letture: http://cpansearch.perl.org/src/GSHANK/Crypt-SaltedHash-0.09/lib/Crypt/SaltedHash.pm
slappasswd
è {SSHA} o la versione salata di SHA-1.