Outils pour utilisateurs

Outils du site


web:php:random

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

web:php:random [le 26/02/2013 à 16:40] – créée Yoskoweb:php:random [le 27/02/2013 à 12:37] (Version actuelle) Yosko
Ligne 1: Ligne 1:
-====== Nombres aléatoires en PHP ======+====== L'aléatoires en PHP ======
  
 **Note : article en cours de rédation** **Note : article en cours de rédation**
Ligne 7: Ligne 7:
 ===== Crypto ===== ===== Crypto =====
 L'utilisation de fonctions telles que ''rand()'' ou ''mt_rand()'' n'est pas considéré comme sécurisé pour une utilisation en cryptographie. S'il existe des fonctions préférables, elles sont généralement inclues dans des modules non installés par défaut. L'utilisation de fonctions telles que ''rand()'' ou ''mt_rand()'' n'est pas considéré comme sécurisé pour une utilisation en cryptographie. S'il existe des fonctions préférables, elles sont généralement inclues dans des modules non installés par défaut.
 +
 +==== Méthode générale (linux) ====
  
 Sous Linux/Unix, une solution consiste à aller lire le fichier /dev/random, qui génère des nombres aléatoires. On peut indiquer le nombre d'octets qu'on souhaite lire : Sous Linux/Unix, une solution consiste à aller lire le fichier /dev/random, qui génère des nombres aléatoires. On peut indiquer le nombre d'octets qu'on souhaite lire :
Ligne 50: Ligne 52:
 En résumé, où **N** est un multiple de 3 : En résumé, où **N** est un multiple de 3 :
   * si le nombre d'octets fournis en entrée de ''base64()'' est **N**, tous les caractères retournés seront réellement aléatoires.   * si le nombre d'octets fournis en entrée de ''base64()'' est **N**, tous les caractères retournés seront réellement aléatoires.
-  * Si il est **N+1**, il y aura un caractère un peu moins aléatoire suivi de 2 ''=''. Il faut donc se débarrasser des 3 derniers caractères. +  * Si il est **N+1**, il y aura caractère un peu moins aléatoire suivi de 2 ''=''. Il faut donc se débarrasser des 3 derniers caractères. 
-  * Si il est **N+2**, il y aura un caractère un peu moins aléatoire suivi de 1 ''=''. Il faut donc se débarrasser des 2 derniers caractères.+  * Si il est **N+2**, il y aura caractère un peu moins aléatoire suivi de 1 ''=''. Il faut donc se débarrasser des 2 derniers caractères.
  
 +Pour calculer le nombre de caractère qu'on va obtenir, ou le nombre de caractère utiles (pour ne garder que l'essentiel), on peut faire :
 +<code php>
 +function base64CharForByteString($length = 1, $usefulCharOnly = false;) {
 +    if($usefulCharOnly === true) {
 +        //number of really random characters returned by base64() for $nbBytes bytes
 +        return (int)($length*8/6);
 +    } else {
 +        //number of characters returned by base64() for $nbBytes bytes
 +        return ((int)(($length+2)/3)) * 4;
 +    }
 +}
 +</code>
  
-Seulement sous Linux/Unix (/dev/urandom). n'utiliser que ponctuellement (génération d'ID de sessionde sel pour hashage de mot de passe, etc...).+l'inverse si on sait le nombre de caractères que l'on souhaitevoici une méthode pour calculer le nombre d'octets qu'il nous faudra en entrée :
 <code php> <code php>
-//31 binary characters from urandom will result in a 42 long base64 encoded string +function bytesNeededForBase64String($length) { 
-$nbBytes = 31+    return ceil($length * 6 / 8)
-//read random bytes from /dev/urandom +
-$random = file_get_contents('/dev/urandom', false, null, 0, $nbBytes);+</code> 
 +Après, il ne reste plus qu'à tronquer notre chaine pour garder la partie "utile".
  
-//turn binary string to readable string +==== random ou urandom ? ==== 
-//(base64 is [a-zA-Z0-9] with also '+and '/', with padding '='+Sur certains systèmes, on peut utiliser au choix le fichier ''/dev/random'' ou le fichier ''/dev/**__u__**random''. 
-$base64 = base64_encode($random); + 
-$base64 str_replace('=''', $base64);+En réalité, si les deux font presque la même chose, urandom utilise une entropie plus faible : 
 +  * inconvéniant : un peu moins sécurisé d'un point de vue cryptographique, car résultat plus déterministe 
 +  * avantage : est capable de générer une plus grande quantité d'octets dans une même période. 
 + 
 +En bref : pour utiliser dans des sels de hashage, il vaut mieux se tourner vers ''/dev/random'', et n'utiliser ''/dev/**__u__**random'' que dans des cas qui nécessitent de //grosses// quantités de données aléatoiresoù ''/dev/random'' ne suffit plus. 
 + 
 +==== Et Windows ? ==== 
 +Il n'existe pas d'équivalent direct à ''/dev/random'' sous Windows. Une solution consiste à utiliser la librairie de George Argyros : [[https://github.com/GeorgeArgyros/Secure-random-bytes-in-PHP|Secure Random Bytes in PHP]]. 
 + 
 +La librairie en question tente de trouver la manière la plus sécurisée disponible sur votre système. Dans l'ordre il tente : 
 +  * openssl_random_pseudo_bytes 
 +  * mcrypt_create_iv 
 +  * /dev/urandom 
 +  * Méthode custom si aucune autre n'est disponible (celui qui sera probablement utilisé sur Windows)
 + 
 +Je conserve sous le coude une copie de ce travail (placé sous licence BSD), au cas où. Pour la télécharger, {{:web:php:secure-random-bytes-in-php-master.zip|cliquez ici}}.
  
-//optionally: turn the string into a usable string in 
-//scripts that dislike the '+' like Blowfish 
-$base64 = str_replace('+', '.', $base64); 
-</code> 
web/php/random.1361896804.txt.gz · Dernière modification : le 26/02/2013 à 16:40 de Yosko