93 votes

Génération de jetons cryptographiquement sécurisés

Afin de générer un jeton de 32 caractères pour l'accès à notre API, nous utilisons actuellement :

$token = md5(uniqid(mt_rand(), true));

J'ai lu que cette méthode n'est pas cryptographiquement sûre car elle est basée sur l'horloge du système, et que openssl_random_pseudo_bytes serait une meilleure solution car elle serait plus difficile à prévoir.

Si c'est le cas, à quoi ressemblerait le code équivalent ?

Je présume quelque chose comme ça, mais je ne sais pas si c'est juste...

$token = md5(openssl_random_pseudo_bytes(32));

Quelle est la longueur logique que je dois passer à la fonction ?

202voto

fire Points 9036

Voici la solution correcte :

$token = bin2hex(openssl_random_pseudo_bytes(16));

# or in php7
$token = bin2hex(random_bytes(16));

10voto

mjsa Points 2746

Si vous voulez utiliser openssl_random_pseudo_bytes, il est préférable d'utiliser l'implémentation de CrytoLib, ce qui vous permettra de générer tous les caractères alphanumériques, en collant bin2hex autour de openssl_random_pseudo_bytes, vous obtiendrez seulement A-F (majuscules) et des chiffres.

Remplacez path/to/ par l'endroit où vous avez placé le fichier cryptolib.php (vous pouvez le trouver sur GitHub à l'adresse : https://github.com/IcyApril/CryptoLib )

<?php
  require_once('path/to/cryptolib.php');
  $token = IcyApril\CryptoLib::randomString(16);
?>

La documentation complète de CryptoLib est disponible à l'adresse suivante : https://cryptolib.ju.je/ . Il couvre beaucoup d'autres méthodes aléatoires, le cryptage en cascade et la génération et la validation de hachages ; mais il est là si vous en avez besoin.

9voto

imichaelmiers Points 2320

Si vous disposez d'un générateur de nombres aléatoires cryptographiquement sécurisé, vous n'avez pas besoin de hacher sa sortie. En fait, vous ne voulez pas le faire. Utilisez simplement

$token  = openssl_random_pseudo_bytes($BYTES,true)

Où $BYTES est le nombre d'octets de données que vous voulez. MD5 a un hachage de 128 bits, donc 16 octets suffiront.

Par ailleurs, aucune des fonctions que vous appelez dans votre code original n'est cryptographiquement sûre, la plupart sont suffisamment dangereuses pour que l'utilisation d'une seule d'entre elles ne soit pas sécurisée, même si elle est combinée avec d'autres fonctions sécurisées. MD5 a des problèmes de sécurité (bien que pour cette application ils ne soient pas pertinents). Uniqid ne génère pas d'octets cryptographiquement aléatoires par défaut (puisqu'il utilise l'horloge système), l'entropie supplémentaire que vous transmettez est combinée à l'aide d'un générateur linéaire congruent, qui n'est pas cryptographiquement sûr. En fait, cela signifie probablement que quelqu'un pourrait deviner toutes vos clés API s'il avait accès à quelques-unes d'entre elles, même s'il n'avait aucune idée de la valeur de l'horloge de votre serveur. Enfin, mt_rand(), que vous utilisez comme entropie supplémentaire, n'est pas non plus un générateur de nombres aléatoires sûr.

0voto

MacroMan Points 1341

Une autre option consiste à utiliser RandomLib de ircmaxell ( https://github.com/ircmaxell/RandomLib )

Installez : composer require ircmaxell/random-lib

Exemple de force moyenne

$factory = new Factory();
$factory->getMediumStrengthGenerator()->generateString(32);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X