1
votes

Chaîne ASCII aléatoire cryptographiquement sécurisée en PHP

Je connais random_bytes () en PHP 7, et je veux l'utiliser pour générer une chaîne aléatoire cryptographiquement sécurisée (par exemple difficile à deviner) à utiliser comme jeton unique ou plus longtemps stockage à terme dans un cookie.

Malheureusement, je ne sais pas comment convertir la sortie de random_bytes () en une chaîne composée uniquement de caractères lisibles par l'homme, donc les navigateurs ne sont pas confus. Je connais bin2hex () , mais je préférerais utiliser la plage ASCII complète au lieu des nombres hexadécimaux, pour plus de bits par longueur.

Des idées?


1 commentaires

En supposant que votre question est simplement de savoir comment convertir des octets en une représentation ASCII et pas nécessairement comment générer une chaîne aléatoire cryptographiquement sécurisée: avez-vous considéré l'encodage Base64 et la fonction base64_encode () en PHP?


3 Réponses :


1
votes

Personnellement, j'utilise juste une bibliothèque GUID et je concatène quelques GUID pour obtenir une longue chaîne de jetons unique. Vous avez également la possibilité de supprimer les tirets pour qu'il soit difficile de connaître la source et si vous voulez la rendre encore plus complexe, vous pouvez réduire aléatoirement la chaîne jusqu'à 10 caractères pour ajouter de la complexité à sa longueur inconnue.

J'utilise cette bibliothèque pour générer mes GUID

https://packagist.org/packages / ramsey / uuid

function randomAsciiString($length) {
    return implode('', array_map(
        function($value) {
            return chr($value);
        },
        array_map(
            function($value) {
                return random_int(33, 126);
            },
            array_fill(0, $length - 1, null)
        )
    ));
}
echo randomAsciiString(128);                  // Normal 128 char string
echo randomAsciiString(random_int(118, 128)); // obfuscated length char string for extra complexity.

Désolé, j'ai oublié la partie sur le fait que vous vouliez utiliser toute la portée de 26 caractères alpha avec numérique ... Je ne suis pas sûr d'avoir une réponse pour vous à cet égard, mais vous devriez avoir confiance en la difficulté de deviner un UUID4, surtout lorsque vous ajoutez un couple et obscurcissez la longueur par un facteur de 10 pour rendre la devinette plus complexe.

En fait , si vous pouviez générer en toute sécurité un tableau de nombres aléatoires dans la plage de codes de caractères ascii valides, vous pourriez convertir l'ensemble du tableau aléatoire de codes en caractères ascii respectifs et les imploser ensemble en une seule chaîne.

use Ramsey\Uuid\Uuid;
$token = Uuid::uuid4() . '-' . Uuid::uuid4();

bien sûr cependant ... vous devez être conscient que vous utilisez toutes les touches standard du clavier et que certains de ces caractères vont bouleverser les choses sensibles ( ex. citations etc.)


3 commentaires

"... mais vous devriez avoir confiance en la difficulté de deviner un UUID4 ..." Non, vous ne devriez pas.


Pourquoi n'auriez-vous pas confiance en sa capacité à générer une chaîne aléatoire de caractères et des personnes ayant du mal à deviner?


Nous savons tous qu'avec suffisamment de temps, de puissance de traitement et d'occasions de percer quelque chose, nous finirons par deviner correctement ... donc techniquement, rien n'est sûr en cryptographie, mais si vous avez de fortes chances que quelque chose ne soit pas deviné et l'appliquer à un puits système conçu qui ne permet pas parfois de le pousser jusqu'à ce que les vaches rentrent à la maison, alors vous serez bien en faisant confiance à UUID4 et plus encore lorsque vous en combinez quelques-uns pour former un UUID4 uber



5
votes

Malheureusement, Peter O. a supprimé sa réponse après avoir reçu une attention négative dans une file d'attente de révision, peut-être parce qu'il l'avait formulée comme une question. Je pense que c'est une réponse légitime, je vais donc la reprendre.

Une solution simple consiste à encoder vos données aléatoires dans l'alphabet base64 en utilisant base64_encode () . Cela ne produira pas la "gamme ASCII complète" comme vous l'avez demandé, mais cela vous en donnera l'essentiel. Une plage ASCII encore plus grande est sortie par un encodeur base85 approprié, mais php n'en a pas intégré. Vous pouvez probablement trouver de nombreux encodeurs open-source base85 pour php. À mon avis, la diminution de la longueur de base85 par rapport à base64 ne vaudra probablement pas le code supplémentaire que vous devez maintenir.


0 commentaires

0
votes

Considérons les lettres à utiliser. Par souci de simplicité, je suppose que vous ne souhaitez utiliser que de grandes et petites lettres anglaises. Cela signifie que vous avez 26 grosses lettres et 26 minuscules, 52 valeurs possibles différentes. Si nous considérons un tableau d'octets de n éléments comme un nombre de n chiffres en base 256 et que nous convertissons ce nombre en un nombre en base 52, où A est 0, B est 1, C est 2, ..., a est 26, ..., z vaut 51, puis la conversion de ces chiffres en lettres correspondantes donnera le texte que vous vouliez.


0 commentaires