IBM : Cryptage des données avec PHP
Par David KAPOLA, jeudi 3 août 2006 à 09:09 :: Lu sur le Web :: #2316 :: rss
Dans ce monde virtuel qu’est Internet, il est important d’apprendre à protéger des données tels des mots de passe, des numéros de carte de crédit et éventuellement des textes entiers.
En tant que développeur PHP, vous devez vous rendre compte que les pratiques en matière de « grosse » sécurité ne doivent pas être appliquées sur quelques applications par ci par la ! Elles doivent l’être sur vos projets en cours !
La cryptographie (racines grecques) est l’art de « l’écriture secrète ». Une des première méthodes pour crypter un texte fut « le chiffre de César ». Cette méthode consiste à décaler les lettres de l'alphabet d'un nombre n. Par exemple, si on remplace A par D (n=3), on remplace B par E, C par F...
Il est à noter que le code de César a été utilisé sur des forums internet sous le nom de ROT13 (rot-ation de 13 lettres ou A-->N...). Le ROT13 n'a pas pour but de rendre du texte confidentiel, mais plutôt d'empêcher la lecture involontaire (d'une réponse à une devinette, ou de l'intrigue d'un film, etc.).
Les techniques de cryptage d’aujourd’hui sont beaucoup plus complexes. Nous n’entrerons pas dans les détails de ces techniques mais nous verrons que les données doivent tout de même être un minimum protégées.
Il n’y a pas de méthode 100% fiable mais il est important de sécuriser votre espace juste assez pour que les hackers ne prennent même pas la peine même d'essayer d’entrer dedans.
Sécurisation des données
Disons que vous êtes un nouveau développeur, vous n’avez jamais eu à protéger vos données. Vous avez créé votre première application et vous stockez des identifiants et de mots de passe non-cryptés dans la base de données. Tout ceux qui ont accès à la base de données peuvent donc les voir car ils sont écrit en clair. Vous avez fait une page d’identification comme celle-ci:
<form action="verify.php" method="post"> <p><label for='username'>Username</label> <input type='text' name='username' id='username'/> </p> <p><label for='password'>Password</label> <input type='text' name='password' id='password'/> </p> <p><input type="submit" name="submit" value="log in"/> </p> </form>
Qu’est-ce qui ne va pas dans ce formulaire ?
Tout d’abord le champ « password » est de type « text » , ce qui signifie que lorsque l’utilisateur saisi sont mot de passe, celui-ci s’affiche à l’écran… !
Il est facilement possible de remédier à ce problème en remplacant le type du champ password en « password ».
Ainsi des étoiles seront affichées à la places des caractères du mot de passe.
Passons maintenant au fichier verify.php qui permet de vérifier les données saisies dans le formulaire.
<?php
$user = $_POST['user'];
$pw = $_POST['password'];
$sql = "select user,password from users
where user='$user'
and password='$pw'
limit 1';
$result = mysql_query($sql);
if (mysql_num_rows($result)){
//Nous avons un résultat
}else{
//pas de résultat
}
?>
Avec ce code, il est facile d’injecter du code SQL dans la requête. Vous devez toujours avoir en tête que les données saisies par l’utilisateur sont toujours erronées !
Il faut donc « nettoyer » ces données.
<?php
$user = strip_tags(substr($_POST['user'],0,32));
$pw = strip_tags(substr($_POST['password'],0,32));
$sql = "select user,password from users
where user='". mysql_real_escape_string($user)."'
and password='". mysql_real_escape_string($pw)."'
limit 1';
$result = mysql_query($sql);
if (mysql_num_rows($result)){
//Nous avons un résultat
}else{
//pas de résultat
}
?>
Avec l’utilisation judicieuse de strip_tags() substr(), et mysql_real_escape_string(), toutes les commandes potentiellement nocives sont impossibles. De plus la longueur des éléments entrés doit être inférieure à 32 caractères et les caractères spéciaux que la base de données pourrait interpréter comme « non-conformes » sont retirés.A ce moment là, le mot de passe n’est toujours pas crypté dans la base de données. Pour parer à ce problème, le plus simple est d’employer la fonction crypt() lors de l’enregistrement d’un nouvel utilisateur pour crypter le mot de passe.
<?php
$user = strip_tags(substr($_POST['user'],0,32));
$pw = strip_tags(substr($_POST['password'],0,32));
$cleanpw = crypt($pw);
$sql = "insert into users (username,password)
values('".mysql_real_escape_string($user)."',
'".mysql_real_escape_string($cleanpw)."')";
//.....etc....
?>
La fonction crypt() prend pour premier argument une chaîne de caractère. Le deuxième argument sera utilisé comme base pour le chiffrement. Si ce deuxième argument n'est pas fourni, PHP en générera un lui-même, à chaque appel à cette fonction.Les applications PHP récentes utilisent MD5 mais il est possible d’utiliser les 2 fonctions en même temps. Vous pouvez également utiliser une autre méthode, selon vos conditions de sécurité et préférences personnelles.
<?php
$user = strip_tags(substr($_POST['user'],0,32));
$pw = strip_tags(substr($_POST['password'],0,32));
$cleanpw = crypt(md5($pw),md5($user));
$sql = "insert into users (username,password)
values('".mysql_real_escape_string($user)."',
'".mysql_real_escape_string($cleanpw)."')";
//.....etc....
?>
Vous avez maintenant un mot de passe chiffré dans votre base de données, mais aucune manière de le déchiffrer . Mais est-ce bien utile ? Il suffit simplement d’encoder de la même manière, le mot de passe que vous récupérez sur la page d’identification, et de le comparer au mot de passe stocké.
<?php
$user = strip_tags(substr($_POST['user'],0,32));
$pw = strip_tags(substr($_POST['password'],0,32));
$cleanpw = crypt(md5($pw),md5($user));
$sql = "select user,password from users
where user='". mysql_real_escape_string($user)."'
and password='". mysql_real_escape_string($cleanpw)."'
limit 1';
$result = mysql_query($sql);
if (mysql_num_rows($result)){
//Nous avons un résultat
}else{
//pas de résultat
}
?>
Par exemple, si le mot de passe chiffré stocké est i83Uw28jKzBrZF, chiffrez le mot de passe entrant et comparez-le à celui stocké dans la base de données. La seule solution pour casser le mot de passe crypté est de le comparer à une liste de mots cryptés. C’est la raison pour laquelle il est déconseillé de prendre le nom d’une célébrité ou même de votre chien ! Pour parer à (presque) toutes les attaques il faut s'assurer votre mot de passe est d'une certaine longueur (huit caractères ou plus) et contient des lettres majuscules, des nombres, et des caractères spéciaux (comme ! et $). Par exemple : « F1D0 » est un meilleur mot de passe, à court terme, qu'un plus long mot de passe comme GandalftheGray, qui est plus long, emploie des lettres minuscules, et est le nom d'un personnage du "seigneur des anneaux" !Chiffrement et déchiffrement avec PHP
La majeure partie de cet article porte sur le cryptage des données en utilisant crypt() . Cela ne fonctionne que dans un seul sens. Comment faire dans ce cas pour décrypter un message ? il faut utiliser une clé publique supportée par PHP.
Les utilisateurs de cryptage à clé publique ont une clé privée et une clé publique et partagent leurs clés publiques avec les autres utilisateurs. Si vous voulez envoyer un message privé à votre ami Mr X, vous cryptez ce message avec la clé publique de Mr X. Lorsque Mr X reçevra ce message, il pourra le décrypter à l’aide de sa clé privée.
La clé publique et la clé privée d’un utilisateur ne sont pas mathématiquement reliées. Avec PGP(Pretty Good Privacy) et les méthodes de cryptage à clé publique, il n’y a aucun moyen de trouver la clé privée d’un utilisateur à partir de la clé publique.
Une sécurité supplémentaire de PGP est que le mot de passe pour la clef privée n'est pas vraiment un mot de passe ; c'est une « passphrase ». Cela peut être une énonciation entière, y compris avec de la ponctuation et des espaces.
Le seul moyen d’utiliser le cryptage par clé publique de PGP est d’utiliser GPG(GNU Privacy Guard). GPG est un logiciel très stable, apte à la production. Ainsi, il est généralement inclus dans les systèmes d'exploitation libres, comme les BSD ou GNU/Linux.
Tous les messages chiffrés avec GPG peuvent être déchiffrés avec GPG, PGP, ou n'importe quel plugin de client webmail. Dans l’exemple, les données sont cryptées à l’aide de GPC et sont envoyées.
<?php //set up utilisateurs $from = "webforms@example.com"; $to = "you@example.com"; //limitation du nombre de caractères du mail et suppression des balises HTML $messagebody = strip_tags(substr($_POST['msg'],0,5000)); $message_body = escapeshellarg($messagebody); $gpg_path = '/usr/local/bin/gpg'; $home_dir = '/htdocs/www'; $user_env = 'web'; $cmd = "echo $message_body | HOME=$home_dir USER=$user_env $gpg_path" . "--quiet --no-secmem-warning --encrypt --sign --armor " . "--recipient $to --local-user $from"; $message_body = `$cmd`; mail($to,'Message from Web Form', $message_body,"From:$from\r\n"); ?>Dans cet exemple, PHP appelle /usr/local/bin/gpg (cet endroit peut changer sur votre serveur) pour chiffrer un message en utilisant la clef privée de l'expéditeur et la clef publique du destinataire. En effet, seulement le destinataire peut déchiffrer le message. Préciser les variables d’environnement HOME et USER permet de dire a GPG où chercher les clefs.
Voici la définition des autres variables :
- --quiet and --no-secmem-warning supprime les warnigs de GPG
- --encrypt rend le crypage plus performant
- --sign ajoute une signature pour vérifier identité de l’expéditeur
- --armor produit des caractères ASCII au lieu de binaires pour faciliter l’envoi par e-mail
Lire l'article complet







Commentaires
#1 - Le jeudi 3 août 2006 à 09:27, par Eric
#2 - Le mardi 22 août 2006 à 01:53, par plumber
#3 - Le dimanche 4 novembre 2007 à 07:15, par wzcocoon
Ajouter un commentaire
Vous pouvez soumettre un commentaire en remplissant le formulaire ci-dessous. Toutes les contributions font l'objet d'une étape de modération par notre équipe.
Le code HTML dans le commentaire sera affiché comme du texte, les adresses internet seront converties automatiquement.