Publié le 30/09/2014
Auteur BlackBear
Réseaux sociaux
0 partages
0 tweets
4 plus
0 commentaires

Enregistrer les logins et les mots de passe

Le nom d'utilisateur et le mot de passe nous permettent de s'authentifier sur les services présents sur internet. Ces informations sont confidentielles puisqu'elles nous permettent de se connecter à des sites internet pour consulter ses comptes bancaires ou effectuer un achat en ligne.
Comment stocker les données personnelles des internautes dans une base MySql avec un niveau de sécurité correcte ?

Mise en place du système de login

Afin de permettre à l'internaute de s'authentifier sur notre site internet, nous avons besoin de mettre en place un formulaire HTML, de créer une table par exemple sous MySql et d'un script PHP pour contrôler l'échange d'information. Le but est d'ouvrir une session sur le serveur Apache pour autoriser l'internaute à consulter des données qui lui sont propres.

Table MySql
A l'aide de l'interface graphique phpMyAdmin ou directement avec une requête SQL, créons une table nommée tb_userlogin qui contient 2 champs UL_USERNAME et UL_PASSWORD. Avec le wrapper Pdo, la création de la table peut s'exécuter ainsi:

$pdo = new PDO(...);
$pdo->exec("CREATE TABLE IF NOT EXISTS tb_userlogin (
           UL_USERNAME VARCHAR(64) PRIMARY KEY NOT NULL UNIQUE,
           UL_PASSWORD VARCHAR(64));");

Sécuriser les données du formulaire
Lorsqu'une donnée est transmise au travers d'un formulaire, il convient de sécuriser les variables avant de les insérer dans une base de donnée. Quel filtre choisir pour éviter les injections SQL ?
Dans cet exemple, nous utiliserons la fonction de filtre de PHP puis les valeurs seront tronquées pour éviter l'ajout de données dans la requete SQL.
$_POST['username'] //nom de l'utilisateur issu du formaire
$_POST['pwd'] //mot de passe transmis par le formulaire

//echapper les caractères incorrectes
$username = filter_var($_POST['username'], FILTER_SANITIZE_STRING);
$password = filter_var($_POST['pwd'], FILTER_SANITIZE_STRING);

//tronquer la taille 
$username = trim(substr($username, 0, 64));
$password = trim(substr($password, 0, 64));

Stocker les identifiants en clair

En suivant uniquement la logique utilisateur, les mots de passe de chacun sont stockés directement dans la base de donnée. L'avantage est de pouvoir restitué le mot de passe à l'internaute en cas d'oubli de celui-ci.

Ajout d'un nouvel utilisateur
$pdo = new PDO(...);
$sth=$pdo->prepare("INSERT INTO tb_userlogin (UL_USERNAME,UL_PASSWORD)
    VALUES (:UL_USERNAME,:UL_PASSWORD)");
$sth->bindParam(':UL_USERNAME',$username , PDO::PARAM_STR, 64);
$sth->bindParam(':UL_PASSWORD', $password, PDO::PARAM_STR, 32);
$sth->execute();

Vérifier l'identifiant et le mot de passe
$pdo = new PDO(...);
$sth=$pdo->prepare("SELECT UL_PASSWORD FROM tb_userlogin WHERE UL_USERNAME=:UL_USERNAME");
$sth->bindParam(':UL_USERNAME',$username , PDO::PARAM_STR, 64);
$sth->execute();
$rs=$sth->fetch(PDO::FETCH_ASSOC);
if (isset($rs['UL_PASSWORD']) && $rs['UL_PASSWORD']==$password) {
    echo 'Hello '.$username;
    @session_start();
} else {
   echo 'User or password are wrong ! '; 
}

Le gros point faible de cette méthode est le risque de se faire voler les informations. Le risque zéro n'existe pas en informatique, un hacker peut pénétrer le système et dérober l'ensemble des données sur ses utilisateurs.

Stocker l'empreinte du mot de passe

L'astuce consiste à convertir le mot de passe en une empreinte. La fonction de hachage transforme un texte en une représentation sous forme de 32 caractères pour le MD5. Ainsi le mot de passe n'apparait plus en clair dans la base de données. Pour corser le tout, on peut ajouter un grain de sel ou salt en anglais lors de la conversion.

Inscription d'un nouveau compte
$salt='grain_de_sel';
$pdo = new PDO('sqlite:' . $file);
$sth=$pdo->prepare("INSERT INTO tb_userlogin (UL_USERNAME,UL_PASSWORD)
    VALUES (:UL_USERNAME,:UL_PASSWORD)");
$sth->bindParam(':UL_USERNAME',$username , PDO::PARAM_STR, 64);
$hash_pwd=md5($password.$salt);
$sth->bindParam(':UL_PASSWORD', $hash_pwd, PDO::PARAM_STR, 32);
$sth->execute();

Vérifier les identifiants
$salt='grain_de_sel';
$pdo = new PDO('sqlite:' . $file);
$sth=$pdo->prepare("SELECT UL_PASSWORD FROM tb_userlogin WHERE UL_USERNAME=:UL_USERNAME");
$sth->bindParam(':UL_USERNAME',$username , PDO::PARAM_STR, 64);
$sth->execute();
$rs=$sth->fetch(PDO::FETCH_ASSOC);
$hash_pwd=md5($password.$salt);
if (isset($rs['UL_PASSWORD']) && $rs['UL_PASSWORD']==$hash_pwd) {
    echo 'Hello '.$username;
    @session_start();
} else {
   echo 'User or password are wrong ! '; 
}

Est-ce que cette solution est sécurisée ?
Disons qu'elle est acceptable ! Que ce soit les fonctions de hachage MD5 ou Sha, les reverse database existent depuis bien longtemps. Ces dictionnaires donnent le mot de passe à partir d'une empreinte. Même le fait d'ajouter un grain de sel ne suffit pas à sécuriser correctement l'enregistrement des mots de passe.

Utiliser une méthode de chiffrement pour le mot de passe

Sur le principe, le chiffrement du mot de passe est proche de la méthode de l'empreinte vue précédemment. L'avantage du chiffrement avec Blowfish est sa lenteur ! Aucune donnée cryptée n'est inviolable, la question est de savoir combien de temps les ordinateurs mettent pour en trouver la clé. D'où l'intérêt de cette fonction, le chiffrement produit une empreinte solide et assez longue à reproduire.

Inscription d'un nouveau compte
//Générer un nouveau grain de sel pour chaque inscription
$binarySalt = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
$salt = substr(strtr(base64_encode($binarySalt), '+', '.'), 0, 22);
$hash = crypt($password, $salt);

//Insérer dans la DB
$pdo = new PDO(...);
$sth = $pdo->prepare("INSERT INTO tb_userlogin (UL_USERNAME,UL_PASSWORD)
    VALUES (:UL_USERNAME,:UL_PASSWORD)");
$sth->bindParam(':UL_USERNAME', $username, PDO::PARAM_STR, 64);
$hash_pwd = $hash;
$sth->bindParam(':UL_PASSWORD', $hash_pwd, PDO::PARAM_STR, 32);
$sth->execute();


Vérifier les identifiants
$pdo = new PDO(...);
$sth = $pdo->prepare("SELECT UL_PASSWORD FROM tb_userlogin WHERE UL_USERNAME=:UL_USERNAME");
$sth->bindParam(':UL_USERNAME', $username, PDO::PARAM_STR, 64);
$sth->execute();
$rs = $sth->fetch(PDO::FETCH_ASSOC);
 
if (isset($rs['UL_PASSWORD']) &&  crypt($password, $rs['UL_PASSWORD']) === $rs['UL_PASSWORD']) {
    echo 'Hello ' . $username;
    @session_start();
} else {
    echo 'User or password are wrong ! ';
}

Comment enregistrer les identifiants des membres

Cet article fait le point sur des techniques de stockage de mots de passe. J'espère que les exemples de génération de hachage et de stockage dans une table pourront vous servir dans vos sites internet.
Pour améliorer la sécurité du système d'authentification, je vous conseille de:
- s'assurer à chaque étape du type de données retournées avant de les traiter,
- vérifier la complexité des mots de passe à l'inscription (longueur minimale, présente de lettre+chiffre, ...),
- bloquer le script lorsque l'utilisateur saisie plusieurs fois le mauvais mot de passe.

Ajouter un commentaire

Les champs marqués d'un * sont obligatoires, les adresses emails se sont pas publiées.

A lire aussi

Réseaux sociaux
Présentation de l'article
Catégorie
php5 - db
Mise a jour
30/09/2014
Visualisation
vu 3038 fois
Public
Internaute
Auteur de la publication
BlackBear
Membre junior
Auteur de 3 articles
|BIO_PSEUDO|
Commentaires récents

Publié par Tom dans java

Hello!
Cependant, mon Eclipse ne reconnait pas HttpLoader comme type valide...
Comment faire pour que ca marc...

Publié par zozo dans logiciel

comment ca marche??????????

Publié par Absolut dans news

Bonjour,
Dans l'outil de localisation d'IP, je ne comprends pas le sens de la rubrique precision dans le Rapport d'analyse de l'adresse IP ex 1/10, 9/10, bonne, ....
Merci

Publié par amelia dans java

pour 30 sa donne 1346269

Publié par stam dans tuto

Le code est interessant. Que doit contenir le fichier index ?