SSHA es un SHA-1 salado. Por defecto, los últimos 4 bytes son la sal. La salida de slappasswd es
'{<Hash Method>}<base64 converted hash and salt>'
Entonces, para probar, si una contraseña de texto sin formato es igual al SHA salado, debe:
- pele el especificador de método hash con, por ejemplo, sed.
- decodificar la cadena base64
- extraer los últimos 4 bytes, esta es la sal
- concatenar la sal a la contraseña de texto sin formato
- Ha golpeado
- comparar
La cadena decodificada en base64 contiene el hash en forma binaria y no se puede imprimir, por lo que lo convertiremos a hexadecimal con od. Los primeros 3 pasos los realiza el siguiente código:
#!/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"
El resultado podría ser:
{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;▒
Así que ahora tenemos que concatenar la sal a la contraseña de texto sin formato y hash, esta vez sin sal! El problema que tuve fue entender que la sal realmente puede ser cualquier carácter, incluidos los caracteres no imprimibles. Para concatenar estos caracteres no imprimibles, utilizaremos printf y sus representaciones hexadecimales:
slappasswd -h {SHA} -s $(printf 'password\xd3\x62\x3b\x87') | sed 's/{SHA}//' | base64 -d | od -A n -t x1
El resultado es:
7c 3b b4 3e 02 83 9f 50 e2 f5 6d 47 30 83 69 3d 74 6a 43 d8
Que es igual al hash anterior. Ahora hemos verificado que esa 'contraseña' coincide con el SHA salado.
Gracias y lecturas adicionales: http://cpansearch.perl.org/src/GSHANK/Crypt-SaltedHash-0.09/lib/Crypt/SaltedHash.pm
slappasswd
es {SSHA}, o la versión salada de SHA-1.