phpfrance
phpfrance
22 octobre 2007, bienvenue sur phpfrance.com...
un problème, une suggestion ? venez discuter dans les forums
accueil
documentation
livres
tutoriaux
chat
forums
aide
documentation
tutoriaux
forums de discussion
chat irc
ressources
actualité
emplois du php
les livres utiles
hébergement
liens
a propos
crédits
sondages
newsletter
contact
tutoriaux
aller au contenu |
aller au menu |
aller à la recherche
la librairie de chiffrement mcrypt [ripat]
par damien,
dimanche 29 janvier 2006 à 14:05 :: php
:: #38
:: rss
1- une rapide d'explication sur la raison de ce document
la documentation officielle sur cette librairie est assez confuse et présente un grand nombre d'algorithmes et de modes de chiffrement différents. chaque algorithme peut utiliser jusqu'à 7 modes de chiffrements différents.
voici quelques-un des algorithmes de la librairie mcrypt:
cast-128
gost
rijndael-128
twofish
arcfour
cast-256
loki97
rijndael-192
saferplus
wake
blowfish-compat
des
rijndael-256
serpent
xtea
blowfish
enigma
rc2
tripledes
et les modes de chiffrement:
cbc
cfb
ctr
ecb
ncfb
nofb
ofb
stream
la doc comporte par ailleurs assez peu d'exemples. il m'a fallu procéder par essais-erreurs pour arriver à quelque-chose d'utilisable et surtout de comprendre le rôle des différents arguments.
je suis très loin d'avoir découvert toutes les possibilités des très nombreuses fonctions de cette librairie. je n'aborde ici que les fonctions les plus courantes et que j'utilise dans mon script de test:
mcrypt_create_iv crée un vecteur d'initialisation (iv)
mcrypt_encrypt fonction de chiffrement proprement dite
mcrypt_decrypt fonction de dé-chiffrement proprement dite
mcrypt_get_iv_size calcule la taille du vecteur d'initialisation
mcrypt_module_get_algo_key_size calcule la taille maximum des clés de chiffrement
pour chacune de ces fonctions, se référer à la doc.
2- pourquoi chiffrer plutôt que hacher?
tout d'abord la cryptographie est une spécialité de haut niveau.
ceci étant dit, il ne faut pas être un génie en répartition aléatoire des nombres premiers pour utiliser les fonctions php. voici donc quelques généralités triviales mais déterminantes dans le choix entre les deux techniques de masquage.
le hachage est injectif (irréversible). une fois haché avec md5 ou sha, il est impossible de retrouver la source sans disposer de moyens considérables du genre super-calculateur de centre de recherche et... beaucoup de temps.
le cryptage (chiffrement) est lui, bijectif. c'est pour cette raison qu'il est utilisé pour stocker ou transmettre des documents sensibles ou pour stocker des mots de passe que l'on veut pouvoir reconstituer. un document crypté est moins inviolable qu'un document haché, surtout avec des clés courtes, mais tout est relatif. mysql utilise et recommande l'utilisation des fonctions aes_encrypt et aes_decrypt.
les fonctions aes_encrypt() et aes_decrypt() ont été ajoutées dans la version 4.0.2 de mysql et peuvent être considérées comme étant les fonctions de cryptographie les plus sûres disponibles actuellement dans mysql. (doc mysql)
ces fonctions mysql sont basées sur l'algorithme rijndael-128 (algo belge, hé oui!) qui existe également dans la librairie mcrypt.
en ce qui me concerne, j'utilise uniquement la cryptographie pour stocker mots de passe et autres données sensibles. et je dors sur mes deux oreilles.
les fonctions de hachage (md5 et sha1) sont beaucoup plus rapides, environ 50 fois. mais ceci est à mettre en perspective avec la fréquence d'utilisation des fonctions de maquillage de texte ou de mots de passe. si on utilise le cryptage pour enregistrer ou vérifier un mot de passe réversible, ces fonctions ne seront pas souvent utilisées.
un peu de lecture intéressante pour vous décrisper quant à l'utilisation du chiffrement plutôt que le hachage:
hachage (ccm)
cryptographie (ccm)
hachage (wickipédia)
cryptographie (wickipédia)
3- comment chiffrer - exemples
j'ai laissé de côté les fonctions obsolètes comme
mcrypt_cbc ou
mcrypt_cfb. je n'ai pas essayé non plus les fonctions de manipulation de modules
mcrypt_generic et
mdecrypt_generic qui sont un peu plus verbeuses. faudrait que je les teste en rapidité contre les fonctions listées plus haut (à faire. note du 26-1-2006: fait. elles sont un poil plus lentes. pas d'intérêt donc.).
comme il s'agit de fonctions réversibles, il y a bien sûr une fonction pour crypter et une autre pour décrypter. il existe, selon ce qui a été compilé sur votre serveur, plusieurs algorithmes de cryptage. et chaque algorithme dispose d'un certain nombre de modes de chiffrement. en ce qui me concerne, j'ai environ 135 combinaisons algorithme-mode sur ce serveur. chaque couple dispose de millions (milliards?) de combinaisons de cryptage en fonction du choix de votre clé secrète et du vecteur d'initialisation (iv). pour casser votre texte crypté, le casseur doit connaître l'algorithme utilisé, le mode de chiffrement, l'iv et la clé secrète. ca fait beaucoup pour un casseur moyen. si, en plus, tous ces éléments sont bien protégés, hors arborescence web et inclus dans vos scripts par include ou bien stockés en base de données, vous ne risquez strictement rien!
de quoi a-t-on besoin pour crypter un texte:
choisir un algorithme (module) présent sur votre serveur
pour cet algo, choisir un mode de chiffrement
choisir une clé secrète qui sera utilisée pour le cryptage et, bien sûr, également pour le décryptage. il faut qu'elle soit la plus longue possible mais pas plus longue que la longueur maximale compatible avec votre algorithme. cette longueur maximale est invariable pour un algo donné. cette clé doit rester secrète et doit donc être stockée hors racine du serveur web et être appelée par include.
fabriquer un vecteur d'initialisation des modules de chiffrements (iv). lui aussi il doit être mis à la bonne longueur pour l'algorithme. cette longueur maximale est invariable pour un algo donné. ce vi ne doit pas nécessairement, ni être secret, ni aléatoire même si c'est mieux. ce iv est obligatoire pour tous les modes sauf le mode ecb et il doit être le même pour le cryptage et décryptage.
pour faire ces choix, vous pouvez consulter le tableau des couples algo-mode disponibles sur votre machine.
assez parlé. un exemple maintenant:
<?php// choix d'un algo, mode$algo = "blowfish"; // ou la constante php mcrypt_blowfish$mode = "nofb"; // ou la constante php mcrypt_mode_nofb // calcul des longueurs max de la clé et de l'iv$key_size = mcrypt_module_get_algo_key_size($algo);$iv_size = mcrypt_get_iv_size($algo, $mode);// si, à ce stade, vous avez une erreur, c'est sans doute que soit l'algo, soit le mode ne sont// pas supportés par votre serveur. utilisez mon script pour choisir des algo-modes compatibles. // création d'un iv aléatoire de la bonne longueur// vous pouvez mettre n'importe quoi dans $iv du moment qu'il est de la bonne longueur$iv = mcrypt_create_iv($iv_size, mcrypt_rand); // choix d'une clé secrète de cryptage/décryptage et mise à longueur$cle = "bonjour, ceci est une clé qui est sans doute trop longue pour le cryptage";$cle = substr($cle, 0, $key_size); // phrase à crypter et cryptage$texte = "mon mot de passe à crypter";$crypte = mcrypt_encrypt($algo, $cle, $texte, $mode, $iv); // décryptage de contrôle$decrypte = mcrypt_decrypt($algo, $cle, $crypte, $mode, $iv); // affichage de contrôleecho " mot de passe à crypter: <b>".$texte. "</b><br /> mot de passe crypté: <b>" .$crypte. "</b><br /> mot de passe décrypté: <b>" .$decrypte."</b><br />";?>
il ne vous reste plus qu'à faire votre fonction perso pour crypter/décrypter aussi facilement qu'avec md5() ou sha1(). rappelez-vous qu'une fois que votre choix algo-mode est fait, vous connaissez également les longueurs de clé et d'iv de cet algo-mode. vous pouvez donc construire une clé secrète et un iv de la bonne longueur une fois pour toute. plus besoin de les calculer à chaque fois!
enfin, un dernier conseil, si vous devez stocker, par exemple un mot de passe en base de données, utilisez soit une colonne de type blob soit, un type varchar avec attribut binary. sinon vous risquez quelques surprises en raison des caractères binaires produits par les fonctions de cryptage.
si vous ne souhaitez pas changer votre type de colonne, il vous faudra convertir vos chaînes cryptées en base 64. voici comment faire (reprise de l'exemple plus haut):
<?php// phrase à crypter et cryptage$texte = "mon mot de passe à crypter";$crypte = mcrypt_encrypt($algo, $cle, $texte, $mode, $iv);$crypte = base64_encode($crypte); // ... ici stockage en bdd. après récupération: // décryptage$crypte = base64_decode($crypte);$decrypte = mcrypt_decrypt($algo, $cle, $crypte, $mode, $iv);?>
si vous voulez tester la librairie installée sur votre serveur, faites tourner les sources de ce script de test et choisissez l'algo selon vos critères. en parlant de ces critères, n'ayant ni l'âme, ni les compétences d'un casseur de code chiffré, je me base sur la réputation d'un algo et surtout sur sa rapidité d'exécution.
si vous êtes du genre parano, choisissez les couples algo-mode les plus lents dont on peut supposer qu'ils sont les plus sécurisés (quoique...)
faites-moi part de vos remarques ou suggestions par mp sur phpfrance.
ripat.
trackbacks
aucun trackback.
les trackbacks pour ce billet sont fermés.
commentaires
1.
le lundi 30 janvier 2006 à
00:06, par
cyrano
très instructif et en fait, je réalise que c'est beaucoup moins compliqué que je ne l'imaginais.
2.
le mardi 14 février 2006 à
09:30, par
bruno
bonjour ripat .
je te remercie pour ce tuto appuyé par un exemple .
joli travail et très intéressant au demeurant .
merci beaucoup .
bruno
3.
le jeudi 2 mars 2006 à
23:57, par
kanatoui
bonjour,
je trouves que c'est une bonne solution
on peut eviter la configuration de l'openssl.
merci.
4.
le vendredi 10 mars 2006 à
10:25, par
eggy
tutorial très interessant et très bien expliqué, cependant je voulais savoir comment stocké la clé de manière sécurisé (bdd ou fichier ?)
merci d'avance
5.
le lundi 20 mars 2006 à
07:28, par
ripat
> tutorial très interessant et très bien expliqué, cependant je voulais savoir comment
> stocké la clé de manière sécurisé (bdd ou fichier ?)
si tu es du genre parano, tu peux la mettre en bdd. en principe tu disposes de la protection supplémentaire du pseudo/mdp de mysql. mais ce pseudo/mdp est également stocké quelque-part pour pouvoir être utilisé dans tes scripts non?
de plus, si tu as une faille dans la sécurité de phpmyadmin....
personnellement, je place la clé, simplement dans un fichier, hors documentroot ne donnant que des droits r (éventuellement w) que pour le seul uid d'apache (www-data, apache, httpd, nobody selon la distro). de cette manière, seul un script php (ou root) pourra y accéder.
6.
le dimanche 16 avril 2006 à
15:21, par
aurélien
trés interessante ce tutorial.
est il possible d'utiliser la librairie mcrypt sans recompiler php ?
7.
le mardi 19 septembre 2006 à
13:58, par
jean manuel
salut,
j'aurais bien voulu récupérer ton script de test pour voir comment tu teste si le serveur possède ou pas le module.
lorsque je clique sur le lien c'est un page html qu'il me propose de télécharger. alors que je m'attends à télécharger une page php.
merci d'avance.
8.
le vendredi 6 octobre 2006 à
11:10, par
gaetan
bonjour,
// message déjà passé sur le forum mais sans réponse merci.
j'ai une chaine cryptée et encodée en base 64 que je passe en variable d'url.
l'encodage en base 64 génère de temps en temps des signes "+" qui, une fois la chaine récupérer via $_get["id"], se transforment en espaces...
résultat impossible de décrypter correctement la chaine sans faire au préalable un str_replace(" ", "+", $_get["id"]);.
ma question est de savoir s'il y a d'autre caractères de l'encodage en base 64 qui peuvent poser problème...
merci
9.
le vendredi 6 octobre 2006 à
19:58, par
damien
gaetan : utilises la fonction urlencode() avant de passer ta chaine dans une url. dans une url un ligne + correspond à un espace.
10.
le jeudi 16 novembre 2006 à
15:09, par
viny
bonjour,
je suis en pleine réflexion concernant le choix de l'algo car après les avoir testés je me rends compte que tous peuvent générer un caractère slash "/" et cela m'amène à dire que cela peut créer un souci quelconque pour atteindre un fichier dont le nom serait crypté.
bien sur on peut utiliser la fonction urlencode mais quand les noms cryptés ne sont pas utilisés dans une url cela peut-il poser un problème.!?
la solution serait d'obtenir un crypatge qui n'utilise que des lettres et des chiffres et ça je ne l'ai pas encore trouvé dans ce qui est proposé.
par conséquent, si vous en connaissez un je suis preneur.
merci
11.
le jeudi 16 novembre 2006 à
16:22, par
mirko
j'ai remarqué que lorsque je crypte un mot de passe par exemple avec ces fonctions , et que je l'insere dans une base de donnée
j'ai des pb de decryptage lorsque je veux le recuperer.... et pas tout le temps c'est bon une fois sur 3....
vraiment étrange
si qq'un a une idee
12.
le jeudi 7 décembre 2006 à
13:32, par
lemoineo
qui a travaillé sur le cryptage en php pour des fichiers qu'on envoie ensuite par mail (avec un programme php bien sûr)
13.
le vendredi 9 mars 2007 à
20:42, par
the386mmx
salut,
bravo pour ce travail, très utile !
pour ma part, je cherche à crypter le nom de fichiers jpg pour qu'ils ne soient pas directement affichables (éviter google image, copie de lien etc.). et via base de donnée qui me communique une référence, retrouver le nom pour afficher la bonne image.
pas besoin d'un haut niveau de sécurité, et il me faut une chaine relativement courte.
14.
le mardi 15 mai 2007 à
13:21, par
mclane1
une petite faute à souligné dans le titre 1 :
une rapide d'explication sur la raison de ce document.
je pense qu'il y a un "d'" en trop.
je dis ca, ca ne me gene pas, c'est juste pour le site. en gros titre ca ne le fait pas trop...lol
ajouter un commentaire
nom ou pseudo :
email (facultatif) :
site web (facultatif) :
commentaire :
le code html dans le commentaire sera affiché comme du texte,
les adresses internet seront converties automatiquement.
se souvenir de mes informations
rechercher
catégories
phpbases de donnéesjavascriptapachecomment faire
tous les tutoriaux
syndication
fil rss
fil rss commentaires
fil atom
fil atom commentaires
propulsé par dotclear
copyright © [actoo sarl] 1999-2005 - contact - données personnelles
phpfrance Précédent 625 Précédent 624 Précédent 623 Précédent 622 Précédent 621 Précédent 620 Précédent 619 Précédent 618 Précédent 617 Précédent 616 Précédent 615 Précédent 614 Précédent 613 Précédent 612 Précédent 611 Précédent 610 Précédent 609 Précédent 608 Précédent 607 Précédent 606 Précédent 605 Précédent 604 Précédent 603 Précédent 602 Précédent 601 Précédent 600 Précédent 599 Précédent 598 Précédent 597 Précédent 596 Suivant 627 Suivant 628 Suivant 629 Suivant 630 Suivant 631 Suivant 632 Suivant 633 Suivant 634 Suivant 635 Suivant 636 Suivant 637 Suivant 638 Suivant 639 Suivant 640 Suivant 641 Suivant 642 Suivant 643 Suivant 644 Suivant 645 Suivant 646 Suivant 647 Suivant 648 Suivant 649 Suivant 650 Suivant 651 Suivant 652 Suivant 653 Suivant 654 Suivant 655 Suivant 656