SSHA é um SHA-1 salgado. Por padrão, os últimos 4 bytes são o sal. A saída do slappasswd é
'{<Hash Method>}<base64 converted hash and salt>'
Portanto, para testar se uma senha de texto sem formatação é igual ao SHA salgado, é necessário:
- retire o especificador do método hash com, por exemplo, sed.
- decodificar a sequência base64
- extrair os últimos 4 bytes, este é o sal
- concatenar o salt para a senha de texto sem formatação
- hash it
- comparar
A string decodificada em base64 contém o hash em formato binário e não pode ser impressa; portanto, a converteremos em hexadecimal com od. As três primeiras etapas estão sendo executadas pelo seguinte 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"
A saída pode 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;▒
Então agora temos que concatenar o sal para a senha de texto sem formatação e hash, desta vez sem sal! O problema que tive foi entender que o sal pode realmente ser qualquer caractere, incluindo caracteres não imprimíveis. Para concatenar esses caracteres não imprimíveis, usaremos printf e suas representações hexadecimais:
slappasswd -h {SHA} -s $(printf 'password\xd3\x62\x3b\x87') | sed 's/{SHA}//' | base64 -d | od -A n -t x1
A saída é:
7c 3b b4 3e 02 83 9f 50 e2 f5 6d 47 30 83 69 3d 74 6a 43 d8
Qual é igual ao hash acima. Agora, verificamos que 'senha' corresponde ao SHA salgado.
Agradecimentos e leituras adicionais: http://cpansearch.perl.org/src/GSHANK/Crypt-SaltedHash-0.09/lib/Crypt/SaltedHash.pm
slappasswd
é {SSHA} ou a versão salgada do SHA-1.