str_random repetir numeros numero number mt_rand generar cadena array aleatorios aleatorio aleatoria php security hash random

repetir - php random string



Generación segura de números aleatorios en PHP (3)

Caso de uso: el botón "Olvidé mi contraseña". No podemos encontrar la contraseña original del usuario porque está almacenada en forma de hash, por lo que lo único que debe hacer es generar una nueva contraseña aleatoria y enviarla por correo electrónico. Esto requiere números aleatorios criptográficamente impredecibles, para los cuales mt_rand no es lo suficientemente bueno, y en general no podemos suponer que un servicio de alojamiento proporcionará acceso al sistema operativo para instalar un módulo criptográfico de números aleatorios, etc., así que estoy buscando un camino generar números aleatorios seguros en PHP.

La solución que he encontrado hasta ahora implica almacenar una semilla inicial, luego para cada llamada,

result = seed seed = sha512(seed . mt_rand())

Esto se basa en la seguridad de la función hash sha512 (la llamada mt_rand es solo para hacer la vida un poco más difícil para un adversario que obtiene una copia de la base de datos).

¿Me estoy perdiendo algo o hay soluciones más conocidas?


PHP se envía con un nuevo conjunto de funciones CSPRNG ( random_bytes() y random_int() ). Es trivial convertir esta última función en una función de generador de cadenas:

<?php /** * Generate a random string, using a cryptographically secure * pseudorandom number generator (random_int) * * For PHP 7, random_int is a PHP core function * For PHP 5.x, depends on https://github.com/paragonie/random_compat * * @param int $length How many characters do we want? * @param string $keyspace A string of all possible characters * to select from * @return string */ function random_str( $length, $keyspace = ''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'' ) { $str = ''''; $max = mb_strlen($keyspace, ''8bit'') - 1; if ($max < 1) { throw new Exception(''$keyspace must be at least two characters long''); } for ($i = 0; $i < $length; ++$i) { $str .= $keyspace[random_int(0, $max)]; } return $str; }

Si necesita usar esto en un proyecto de PHP 5, no dude en tomar una copia de random_compat , que es un random_compat para estas funciones.


Recomiendo dirigirse a / dev / urandom en los sistemas Unix o al crypto-api en la plataforma de Windows como una fuente de entropía para las contraseñas.

No puedo enfatizar lo suficiente la importancia de comprender que los hashes NO son dispositivos que aumentan la entropía mágica. Mal usarlos de esta manera no es más seguro que usar los datos de semilla y rand () antes de que se haya procesado y estoy seguro de que reconoces que no es una buena idea. La semilla se cancela (mt_rand () determinista) y entonces no tiene sentido incluirla.

Las personas piensan que son inteligentes y astutos, y el resultado de su trabajo son los sistemas y dispositivos frágiles que ponen en peligro la seguridad de sus sistemas y la seguridad de otros sistemas (a través de malos consejos).

Dos errores no hacen un bien. Un sistema es tan fuerte como su parte más débil. Esta no es una licencia o excusa para aceptar que sea aún más inseguro.

Aquí hay un código PHP para obtener una cadena segura de 128 bits al azar, de este comentario en php.net por Mark Seecof :

"Si necesita algunos bits pseudoaleatorios para fines de seguridad o criptográficos (huevo, IV aleatorio para el cifrado de bloques, sal aleatoria para el hash de contraseñas) mt_rand () es una fuente deficiente. En la mayoría de las plataformas Unix / Linux y / o MS-Windows puede obtener una mejor calidad de bits pseudoaleatorios del sistema operativo o la biblioteca del sistema, como esta:

<?php // get 128 pseudorandom bits in a string of 16 bytes $pr_bits = ''''; // Unix/Linux platform? $fp = @fopen(''/dev/urandom'',''rb''); if ($fp !== FALSE) { $pr_bits .= @fread($fp,16); @fclose($fp); } // MS-Windows platform? if (@class_exists(''COM'')) { // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx try { $CAPI_Util = new COM(''CAPICOM.Utilities.1''); $pr_bits .= $CAPI_Util->GetRandom(16,0); // if we ask for binary data PHP munges it, so we // request base64 return value. We squeeze out the // redundancy and useless ==CRLF by hashing... if ($pr_bits) { $pr_bits = md5($pr_bits,TRUE); } } catch (Exception $ex) { // echo ''Exception: '' . $ex->getMessage(); } } if (strlen($pr_bits) < 16) { // do something to warn system owner that // pseudorandom generator is missing } ?>

NB: generalmente es seguro dejar el intento de leer / dev / urandom y el intento de acceder a CAPICOM en su código, aunque cada uno de ellos fallará silenciosamente en la plataforma del otro. Déjalos allí para que tu código sea más portátil ".


También puede considerar usar OpenSSL openssl_random_pseudo_bytes, está disponible desde PHP 5.3.

string openssl_random_pseudo_bytes ( int $length [, bool &$crypto_strong ] )

Genera una cadena de bytes pseudoaleatorios, con el número de bytes determinado por el parámetro de longitud. También indica si se utilizó un algoritmo criptográficamente fuerte para producir los bytes pseudoaleatorios, y lo hace a través del parámetro crypto_strong opcional. Es raro que esto sea FALSO, pero algunos sistemas pueden estar rotos o viejos.

http://www.php.net/manual/en/function.openssl-random-pseudo-bytes.php

Desde PHP 7 también random_bytes función random_bytes disponible

string random_bytes ( int $length )

http://php.net/manual/en/function.random-bytes.php