Définition :

Un hash, c’est une empreinte digitale numérique unique et de taille fixe créée à partir de n’importe quelle donnée, qui permet de l’identifier et de vérifier qu’elle n’a pas été modifiée.

Un exemple de code pour comprendre la notion de hash !

hash_simple.c

#include <stdio.h>

/* Fonction hash très simple */
int hash_simple(char *mot) 
{
    int code = 0;    
    while (*mot != '\0') {
        code = code + *mot;  /* Additionne les codes des lettres */
        mot++;
    }    
    return code % 100;  /* Garde juste 2 chiffres */
}

int main() 
{
    printf("Hash de 'chat' : %d\n", hash_simple("chat"));
    printf("Hash de 'chien' : %d\n", hash_simple("chien"));
    printf("Hash de 'chat' à nouveau : %d\n", hash_simple("chat"));   
    return EXIT_SUCCESS;
}
Hash de 'chat' : 42
Hash de 'chien' : 57  
Hash de 'chat' à nouveau : 42  ← Toujours pareil!

Sous Linux il existe des outils de Hash puissant :

# 1. Crée un fichier
echo "Mon premier hash" > test.txt

# 2. Vois son empreinte
md5sum test.txt

# 3. Modifie-le un tout petit peu
echo "Mon premier hash!" > test.txt  # Ajout d'un '!'

# 4. Vois comme l'empreinte change complètement!
md5sum test.txt

Sous linux le fichier shadow utilise le hash

etudiant:$y$j9T$PyMT0isnkPIZyB6gthk9r0$cGTbYOHh61zf3sRMnese.IZC0c7v5CCZCPMj8fO4MB5:20280:0:99999:7:::

pour information le mot de passe ici est « etudiant »

Champ par champ :

  1. etudiant: → Nom d’utilisateur
  2. $y$j9T$PyMT0isnkPIZyB6gthk9r0$cGTbYOHh61zf3sRMnese.IZC0c7v5CCZCPMj8fO4MB5 → Hash du mot de passe (détaillé ci-dessous)
  3. 20280 → Date du dernier changement (en jours depuis le 1er janvier 1970)
  4. 0 → Âge minimum avant changement (0 = peut changer immédiatement)
  5. 99999 → Âge maximum avant expiration (99999 = jamais)
  6. 7 → Période d’avertissement avant expiration (7 jours)
  7. : → Période de grâce après expiration (vide = aucune)
  8. : → Date d’expiration absolue (vide = jamais)
  9. : → Réservé pour usage futur

Analyse du Hash

$y$j9T$PyMT0isnkPIZyB6gthk9r0$cGTbYOHh61zf3sRMnese.IZC0c7v5CCZCPMj8fO4MB5
$y$ : est l’algorithme utilisé. Algorithme yescrypt (moderne, sécurisé)
j9T : Sel (salt). Salt (3 caractères - la partie "publique" pour rendre le hash unique)
$   : séparateur

PyMT0isnkPIZyB6gthk9r0 : Sel complété (22 caractères en base64)
GTbYOHh61zf3sRMnese.IZC0c7v5CCZCPMj8fO4MB5 : Hash réel (43 caractères)

Tester un mot de passe avec ce hash

apt install whois
echo -n "etudiant" | mkpasswd --method=yescrypt --salt='$y$j9T$PyMT0isnkPIZyB6gthk9r0' --stdin | grep -q '\$y\$j9T\$PyMT0isnkPIZyB6gthk9r0\$cGTbYOHh61zf3sRMnese.IZC0c7v5CCZCPMj8fO4MB5' && echo "OK" || echo "KO"

on test le hash en une ligne .

etudiant@ordi:~/Works/hash_salt/bash$ echo -n "etudiant" | mkpasswd --method=yescrypt --salt='$y$j9T$PyMT0isnkPIZyB6gthk9r0' --stdin | grep -q '\$y\$j9T\$PyMT0isnkPIZyB6gthk9r0\$cGTbYOHh61zf3sRMnese.IZC0c7v5CCZCPMj8fO4MB5' && echo "OK" || echo "KO"
OK
etudiant@ordi:~/Works/hash_salt/bash$ echo -n "etodiant" | mkpasswd --method=yescrypt --salt='$y$j9T$PyMT0isnkPIZyB6gthk9r0' --stdin | grep -q '\$y\$j9T\$PyMT0isnkPIZyB6gthk9r0\$cGTbYOHh61zf3sRMnese.IZC0c7v5CCZCPMj8fO4MB5' && echo "OK" || echo "KO"
KO
etudiant@ordi:~/Works/hash_salt/bash$ 

un petit script shell:

#!/bin/bash
echo "=== Vérificateur de Hash Yescrypt ==="
echo

# Demander le mot de passe (ne s'affiche pas à l'écran)
read -sp "Entrez le mot de passe: " password
echo

# Hash connu de /etc/shadow
known_hash="\$y\$j9T\$PyMT0isnkPIZyB6gthk9r0\$cGTbYOHh61zf3sRMnese.IZC0c7v5CCZCPMj8fO4MB5"

# Extraire le sel du hash connu
salt=$(echo "$known_hash" | cut -d'$' -f1-4)

echo "Sel extrait: $salt"
echo

# Générer le hash avec le même sel
if command -v mkpasswd >/dev/null 2>&1; then
    generated_hash=$(echo -n "$password" | mkpasswd --method=yescrypt --salt="$salt" --stdin)
elif command -v python3 >/dev/null 2>&1; then
    generated_hash=$(python3 -c "import crypt; print(crypt.crypt('$password', '$salt'))")
else
    echo "Erreur: ni mkpasswd ni python3 n'est installé"
    exit 1
fi

echo "Hash généré: $generated_hash"
echo "Hash connu:   $known_hash"
echo

# Comparaison
if [ "$generated_hash" = "$known_hash" ]; then
    echo "✅ SUCCÈS : Les hashs correspondent !"
else
    echo "❌ ÉCHEC : Les hashs sont différents"
    echo "Soit le mot de passe est incorrect, soit il y a un problème de sel"
fi
etudiant@ordi:~/Works/hash_salt/bash$ ./test_hash.sh 
=== Vérificateur de Hash Yescrypt ===

Entrez le mot de passe: 
Sel extrait: $y$j9T$PyMT0isnkPIZyB6gthk9r0

Hash généré: $y$j9T$PyMT0isnkPIZyB6gthk9r0$cGTbYOHh61zf3sRMnese.IZC0c7v5CCZCPMj8fO4MB5
Hash connu:   $y$j9T$PyMT0isnkPIZyB6gthk9r0$cGTbYOHh61zf3sRMnese.IZC0c7v5CCZCPMj8fO4MB5

✅ SUCCÈS : Les hashs correspondent !
etudiant@ordi:~/Works/hash_salt/bash$