web-dev-qa-db-fra.com

Génération de jetons sécurisés de manière cryptographique

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

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

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

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

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

$token = md5(openssl_random_pseudo_bytes(32));

Aussi, quelle longueur a du sens que je devrais passer à la fonction?

72
fire

Voici la solution correcte:

$token = bin2hex(openssl_random_pseudo_bytes(16));

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

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

Remplacez chemin/vers/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 = CryptoLib::randomString(16);
?>

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

10
mjsa

Si vous disposez d'un générateur de nombre aléatoire cryptographiquement sécurisé, vous n'avez pas besoin de hacher sa sortie. En fait, vous ne voulez pas. Juste utiliser

$token  = openssl_random_pseudo_bytes($BYTES,true)

Où $ BYTES correspond toutefois au nombre d'octets de données que vous souhaitez. MD5 a un hachage de 128 bits, donc 16 octets suffiront.

De plus, aucune des fonctions que vous appelez dans votre code d'origine n'est sécurisée sur le plan cryptographique. La plupart d'entre elles sont suffisamment dommageables pour que l'utilisation d'une seule de ces fonctions ne soit pas sécurisée, même si elle est associée à d'autres fonctions sécurisées. MD5 a des problèmes de sécurité (bien que pour cette application, ils peuvent ne pas être pertinents). Uniqid non seulement ne génère pas d'octets cryptographiquement aléatoires par défaut (puisqu'il utilise l'horloge système), l'entropie ajoutée que vous transmettez est combinée à l'aide d'un générateur congruent linéaire, qui n'est pas sécurisé du point de vue cryptographique. En fait, cela signifie probablement que vous pourriez deviner toutes vos clés d'API si vous en avez accès à certaines d'entre elles, même si elles n'avaient 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écurisé.

8
imichaelmiers