Cifrado bidireccional: necesito almacenar contraseñas que se puedan recuperar


Estoy creando una aplicación que almacenará contraseñas, que el usuario puede recuperar y ver. Las contraseñas son para un dispositivo de hardware, por lo que la comprobación contra hashes está fuera de la cuestión.

Lo que necesito saber es:

  1. ¿Cómo puedo cifrar y descifrar una contraseña en PHP?

  2. ¿Cuál es el algoritmo más seguro para cifrar las contraseñas?

  3. ¿Dónde almaceno la clave privada?

  4. En lugar de almacenar la clave privada, ¿es buena idea exigir a los usuarios que introduzcan la clave privada cada vez que necesiten descifrar una contraseña? (Los usuarios de esta aplicación pueden ser de confianza)

  5. ¿De qué maneras se puede robar y descifrar la contraseña? ¿Qué necesito saber?

Author: jww, 2011-02-23

8 answers

Personalmente, usaría mcrypt como otros publicados. Pero hay mucho más que señalar...

  1. ¿Cómo puedo cifrar y descifrar una contraseña en PHP?

    Vea a continuación una clase fuerte que se encarga de todo por usted:

  2. ¿Cuál es el algoritmo más seguro para cifrar las contraseñas?

    ¿el más seguro? cualquiera de ellos. El método más seguro si vas a cifrar es proteger contra vulnerabilidades de divulgación de información (XSS, inclusión remota, etc.). Si sale, el atacante puede eventualmente descifrar el cifrado (ningún cifrado es 100% no reversible sin la clave, como @NullUserException señala que esto no es del todo cierto. Hay algunos esquemas de cifrado que son imposibles de descifrar, como OneTimePad ).

  3. ¿Dónde almaceno la clave privada?

    Lo que haría es usar 3 teclas. Uno es suministrado por el usuario, uno es específico de la aplicación y el otro es específico del usuario (como un sal). La clave específica de la aplicación se puede almacenar en cualquier lugar (en un archivo de configuración fuera de la raíz web, en una variable ambiental, etc.). El usuario específico se almacenaría en una columna en la base de datos junto a la contraseña cifrada. El usuario suministrado no sería almacenado. Entonces, harías algo como esto:

    $key = $userKey . $serverKey . $userSuppliedKey;
    

    El beneficio allí, es que cualquier 2 de las claves se pueden comprometer sin que los datos se vean comprometidos. Si hay un ataque de inyección SQL, pueden obtener el $userKey, pero no los otros 2. Si hay un exploit de servidor local, pueden obtener $userKey y $serverKey, pero no el tercero $userSuppliedKey. Si van a golpear al usuario con una llave, pueden obtener el $userSuppliedKey, pero no el otro 2 (pero de nuevo, si el usuario es golpeado con una llave, llegas demasiado tarde de todos modos).

  4. En lugar de almacenar la clave privada, ¿es una buena idea requerir a los usuarios que ingresen la clave privada cada vez que necesiten descifrar una contraseña? (Los usuarios de esta aplicación pueden ser trusted)

    Absolutamente. De hecho, esa es la única forma en que lo haría. De lo contrario, tendría que almacenar una versión sin cifrar en un formato de almacenamiento duradero (memoria compartida como APC o memcached, o en un archivo de sesión). Eso es exponerse a compromisos adicionales. Nunca almacene la versión sin cifrar de la contraseña en nada excepto en una variable local.

  5. ¿De qué maneras se puede robar y descifrar la contraseña? ¿Qué necesito saber?

    Cualquiera forma de compromiso de sus sistemas les permitirá ver los datos cifrados. Si pueden inyectar código o acceder a su sistema de archivos, pueden ver los datos descifrados (ya que pueden editar los archivos que descifran los datos). Cualquier forma de Repetición o ataque MITM también les dará acceso completo a las claves involucradas. Olfatear el tráfico HTTP sin procesar también les dará las claves.

    Utilice SSL para todo el tráfico. Y asegúrese de que nada en el servidor tenga ningún tipo de vulnerabilidades (CSRF, XSS, Inyección SQL, Escalado de Privilegios, Ejecución Remota de Código, etc.).

Edit: Aquí está una implementación de clase PHP de un método de cifrado fuerte:

/**
 * A class to handle secure encryption and decryption of arbitrary data
 *
 * Note that this is not just straight encryption.  It also has a few other
 *  features in it to make the encrypted data far more secure.  Note that any
 *  other implementations used to decrypt data will have to do the same exact
 *  operations.  
 *
 * Security Benefits:
 *
 * - Uses Key stretching
 * - Hides the Initialization Vector
 * - Does HMAC verification of source data
 *
 */
class Encryption {

    /**
     * @var string $cipher The mcrypt cipher to use for this instance
     */
    protected $cipher = '';

    /**
     * @var int $mode The mcrypt cipher mode to use
     */
    protected $mode = '';

    /**
     * @var int $rounds The number of rounds to feed into PBKDF2 for key generation
     */
    protected $rounds = 100;

    /**
     * Constructor!
     *
     * @param string $cipher The MCRYPT_* cypher to use for this instance
     * @param int    $mode   The MCRYPT_MODE_* mode to use for this instance
     * @param int    $rounds The number of PBKDF2 rounds to do on the key
     */
    public function __construct($cipher, $mode, $rounds = 100) {
        $this->cipher = $cipher;
        $this->mode = $mode;
        $this->rounds = (int) $rounds;
    }

    /**
     * Decrypt the data with the provided key
     *
     * @param string $data The encrypted datat to decrypt
     * @param string $key  The key to use for decryption
     * 
     * @returns string|false The returned string if decryption is successful
     *                           false if it is not
     */
    public function decrypt($data, $key) {
        $salt = substr($data, 0, 128);
        $enc = substr($data, 128, -64);
        $mac = substr($data, -64);

        list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

        if (!hash_equals(hash_hmac('sha512', $enc, $macKey, true), $mac)) {
             return false;
        }

        $dec = mcrypt_decrypt($this->cipher, $cipherKey, $enc, $this->mode, $iv);

        $data = $this->unpad($dec);

        return $data;
    }

    /**
     * Encrypt the supplied data using the supplied key
     * 
     * @param string $data The data to encrypt
     * @param string $key  The key to encrypt with
     *
     * @returns string The encrypted data
     */
    public function encrypt($data, $key) {
        $salt = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
        list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

        $data = $this->pad($data);

        $enc = mcrypt_encrypt($this->cipher, $cipherKey, $data, $this->mode, $iv);

        $mac = hash_hmac('sha512', $enc, $macKey, true);
        return $salt . $enc . $mac;
    }

    /**
     * Generates a set of keys given a random salt and a master key
     *
     * @param string $salt A random string to change the keys each encryption
     * @param string $key  The supplied key to encrypt with
     *
     * @returns array An array of keys (a cipher key, a mac key, and a IV)
     */
    protected function getKeys($salt, $key) {
        $ivSize = mcrypt_get_iv_size($this->cipher, $this->mode);
        $keySize = mcrypt_get_key_size($this->cipher, $this->mode);
        $length = 2 * $keySize + $ivSize;

        $key = $this->pbkdf2('sha512', $key, $salt, $this->rounds, $length);

        $cipherKey = substr($key, 0, $keySize);
        $macKey = substr($key, $keySize, $keySize);
        $iv = substr($key, 2 * $keySize);
        return array($cipherKey, $macKey, $iv);
    }

    /**
     * Stretch the key using the PBKDF2 algorithm
     *
     * @see http://en.wikipedia.org/wiki/PBKDF2
     *
     * @param string $algo   The algorithm to use
     * @param string $key    The key to stretch
     * @param string $salt   A random salt
     * @param int    $rounds The number of rounds to derive
     * @param int    $length The length of the output key
     *
     * @returns string The derived key.
     */
    protected function pbkdf2($algo, $key, $salt, $rounds, $length) {
        $size   = strlen(hash($algo, '', true));
        $len    = ceil($length / $size);
        $result = '';
        for ($i = 1; $i <= $len; $i++) {
            $tmp = hash_hmac($algo, $salt . pack('N', $i), $key, true);
            $res = $tmp;
            for ($j = 1; $j < $rounds; $j++) {
                 $tmp  = hash_hmac($algo, $tmp, $key, true);
                 $res ^= $tmp;
            }
            $result .= $res;
        }
        return substr($result, 0, $length);
    }

    protected function pad($data) {
        $length = mcrypt_get_block_size($this->cipher, $this->mode);
        $padAmount = $length - strlen($data) % $length;
        if ($padAmount == 0) {
            $padAmount = $length;
        }
        return $data . str_repeat(chr($padAmount), $padAmount);
    }

    protected function unpad($data) {
        $length = mcrypt_get_block_size($this->cipher, $this->mode);
        $last = ord($data[strlen($data) - 1]);
        if ($last > $length) return false;
        if (substr($data, -1 * $last) !== str_repeat(chr($last), $last)) {
            return false;
        }
        return substr($data, 0, -1 * $last);
    }
}

Tenga en cuenta que estoy usando una función añadida en PHP 5.6: hash_equals. Si está en una versión inferior a 5.6, puede usar esta función sustituta que implementa una función comparación segura de tiempo usando verificación doble HMAC :

function hash_equals($a, $b) {
    $key = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
    return hash_hmac('sha512', $a, $key) === hash_hmac('sha512', $b, $key);
}

Uso:

$e = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
$encryptedData = $e->encrypt($data, $key);

Entonces, a descifrar:

$e2 = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
$data = $e2->decrypt($encryptedData, $key);

Tenga en cuenta que usé $e2 la segunda vez para mostrar que diferentes instancias todavía descifrarán correctamente los datos.

Ahora, cómo funciona/por qué usarlo sobre otra solución:

  1. Teclas

    • Las llaves no se utilizan directamente. En su lugar, la clave es estirada por una derivación PBKDF2 estándar.

    • La clave utilizada para el cifrado es única para cada bloque de texto cifrado. Por lo tanto, la clave suministrada se convierte en un "llave maestra". Por lo tanto, esta clase proporciona rotación de claves para claves de cifrado y autenticación.

    • NOTA IMPORTANTE , el parámetro $rounds está configurado para claves aleatorias verdaderas de suficiente fuerza (128 bits de aleatorios criptográficamente seguros como mínimo). Si va a usar una contraseña, o una clave no aleatoria (o menos aleatoria entonces 128 bits de CS random), debe aumentar este parámetro. Yo sugeriría un mínimo de 10000 para contraseñas (cuanto más se puede permitir, el mejor, pero se sumará al tiempo de ejecución)...

  2. Integridad de los datos

    • La versión actualizada utiliza ENCRYPT-THEN-MAC, que es un método mucho mejor para garantizar la autenticidad de los datos cifrados.
  3. Cifrado:

    • Utiliza mcrypt para realizar el cifrado. Yo sugeriría usar MCRYPT_BLOWFISH o MCRYPT_RIJNDAEL_128 cifradores y MCRYPT_MODE_CBC para el modo. Es lo suficientemente fuerte, y todavía bastante rápido (un cifrado y el ciclo de descifrado tarda aproximadamente 1/2 segundo en mi máquina).

Ahora, en cuanto al punto 3 de la primera lista, lo que eso le daría es una función como esta:

function makeKey($userKey, $serverKey, $userSuppliedKey) {
    $key = hash_hmac('sha512', $userKey, $serverKey);
    $key = hash_hmac('sha512', $key, $userSuppliedKey);
    return $key;
}

Se podría estirar en la función makeKey(), pero ya que se va a estirar más tarde, no hay realmente un gran punto para hacerlo.

En cuanto al tamaño de almacenamiento, depende del texto sin formato. Blowfish utiliza un tamaño de bloque de 8 bytes, por lo que tendrá:

  • 16 bytes para la sal
  • 64 bytes para el hmac
  • longitud de los datos
  • Relleno para que la longitud de los datos % 8 = = 0

Así que para una fuente de datos de 16 caracteres, habrá 16 caracteres de datos a cifrar. Eso significa que el tamaño real de los datos cifrados es de 16 bytes debido al relleno. Luego agregue los 16 bytes para la sal y 64 bytes para el hmac y el tamaño total almacenado es de 96 bytes. Así que hay en el mejor de los casos una sobrecarga de 80 caracteres, y en el peor de los casos una sobrecarga de 87 caracteres...

I espero que eso ayude...

Nota: 12/11/12: Acabo de actualizar esta clase con un método de cifrado mucho mejor, utilizando claves derivadas mejores y arreglando la generación de MAC...

 203
Author: ircmaxell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-27 13:18:25

¿Cómo puedo cifrar y descifrar una contraseña en PHP? Mediante la implementación de uno de los muchos algoritmos de cifrado. (o usando una de las muchas bibliotecas)

¿Cuál es el algoritmo más seguro para cifrar las contraseñas? Hay toneladas de algoritmos diferentes, ninguno de los cuales es 100% seguro. Pero muchos de ellos son lo suficientemente seguros para el comercio e incluso con fines militares

¿Dónde almaceno la clave privada? Si ha decidido implementar clave pública-algoritmo de criptografía (por ejemplo, RSA), no almacena la clave privada. el usuario tiene clave privada. su sistema tiene una clave pública que podría almacenarse en cualquier lugar que desee.

En lugar de almacenar la clave privada, ¿es una buena idea requerir a los usuarios que ingresen la clave privada cada vez que necesiten descifrar una contraseña? (Los usuarios de esta aplicación pueden ser de confianza) Bueno, si tu usuario puede recordar números primos ridículamente largos, entonces-sí, por qué no. Pero generalmente tendrías que venir arriba con el sistema que permitirá al usuario almacenar su clave en algún lugar.

¿De qué maneras se puede robar y descifrar la contraseña? ¿Qué necesito saber? Esto depende del algoritmo utilizado. Sin embargo, siempre asegúrese de no enviar la contraseña sin cifrar hacia o desde el usuario. Cifrar / descifrar en el lado del cliente, o utilizar https (u otros medios criptográficos del usuario para asegurar la conexión entre el servidor y el cliente).

Sin embargo, si todo lo que necesita es almacene las contraseñas de forma encriptada, le sugeriría que use un cifrado XOR simple. El principal problema con este algoritmo es que podría ser fácilmente roto por el análisis de frecuencia. Sin embargo, como en general las contraseñas no están hechas de párrafos largos de texto en inglés, no creo que deba preocuparse por ello. El segundo problema con el cifrado XOR es que si tiene un mensaje tanto en forma cifrada como descifrada, podría encontrar fácilmente la contraseña con la que se cifró. Una vez más, no es un gran problema en su caso, ya que solo afecta al usuario que ya se vio comprometido por otros medios.

 14
Author: Ivan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-23 11:49:22
  1. La función PHP que buscas es Mcrypt ( http://www.php.net/manual/en/intro.mcrypt.php).

El ejemplo del manual está ligeramente editado para este ejemplo):

<?php
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "This is a very secret key";
$pass = "PasswordHere";
echo strlen($pass) . "\n";

$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $pass, MCRYPT_MODE_ECB, $iv);
echo strlen($crypttext) . "\n";
?>

Utilizaría mcrypt_decrypt para descifrar la contraseña.

  1. El mejor algoritmo es bastante subjetivo: pregunte a 5 personas, obtenga 5 respuestas. Personalmente, si el defecto (Pez globo) no es lo suficientemente bueno para usted, es probable que tenga problemas más grandes!

  2. Dado que es necesario por PHP para cifrar-no estoy seguro de que se puede ocultar en cualquier lugar - comentarios de bienvenida sobre esto. Las mejores prácticas de codificación estándar de PHP se aplican, por supuesto!

  3. Dado que la clave de cifrado estará en su código de todos modos, no estoy seguro de lo que ganará, siempre que el resto de su aplicación sea segura.

  4. Obviamente, si la contraseña encriptada y la clave de encriptación son robadas, entonces se acabó el juego.

Pondría un jinete en mi respuesta - No soy un experto en PHP crypto, pero, creo que lo que he respondido es la práctica estándar-Doy la bienvenida a los comentarios que otros puedan tener.

 12
Author: Jon Rhoades,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-22 04:44:05

Muchos usuarios han sugerido usar mcrypt... lo cual es correcto, pero me gusta ir un paso más allá para que sea fácil de almacenar y transferir (ya que a veces los valores cifrados pueden hacer que sean difíciles de enviar utilizando otras tecnologías como curl o json).

Después de haber cifrado con éxito usando mcrypt, ejecútelo a través de base64_encode y luego conviértalo a código hexadecimal. Una vez en código hexadecimal es fácil de transferir en una variedad de maneras.

$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$key = substr("SUPERSECRETKEY",0,mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$encrypted = mcrypt_generic($td, $unencrypted);
$encrypted = $ua."||||".$iv;
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$encrypted = base64_encode($encrypted);
$encrypted = array_shift(unpack('H*', $encrypted));

Y en el otro lado:

$encrypted = pack('H*', $encrypted);
$encrypted = base64_decode($encrypted);
list($encrypted,$iv) = explode("||||",$encrypted,2);
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$key = substr("SUPERSECRETKEY",0,mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$unencrypted = mdecrypt_generic($td, $encrypted);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
 6
Author: Bradley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-25 23:20:21

Solo sugeriría cifrado de clave pública si desea la capacidad de establecer la contraseña de un usuario sin su interacción (esto puede ser útil para restablecer y contraseñas compartidas).

Clave pública

  1. La extensión OpenSSL , específicamente openssl_public_encrypt y openssl_private_decrypt
  2. Esto sería RSA recta suponiendo que sus contraseñas encajarán en el tamaño de la clave - relleno, de lo contrario se necesita una capa simétrica
  3. Almacena ambas claves para cada usuario, la contraseña de la clave privada es su contraseña de la aplicación

Simétrico

  1. La extensión Mcrypt
  2. AES-256 es probablemente una apuesta segura, pero esto podría ser una pregunta en sí misma
  3. No lo hace-esta sería su contraseña de aplicación

Ambos

4. Sí, los usuarios tendrían que ingresar la contraseña de su aplicación cada vez, pero almacenarla en la sesión plantearía otros problemas

5.

  • Si alguien roba los datos de la aplicación, es como seguro como el cifrado simétrico (para el esquema de clave pública, se usa para proteger la clave privada con la frase de contraseña.)
  • Definitivamente, su aplicación solo debe ser accesible a través de SSL, preferiblemente utilizando certificados de cliente.
  • Considere agregar un segundo factor para la autenticación que solo se usaría una vez por sesión, como un token enviado a través de SMS.
 5
Author: Long Ears,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-23 11:57:33

Probé algo como esto, pero tenga en cuenta que no soy criptógrafo ni tengo un conocimiento profundo sobre php o cualquier lenguaje de programación. Es sólo una idea. Mi idea es almacenar key en algún archivo o database (o introducir manualmente) que(ubicación) no se puede predecir fácilmente(Y, por supuesto, cualquier cosa se descifrará algún día, el concepto es alargar el tiempo de descifrado) y cifrar la información confidencial.

$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH , MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "evenifyouaccessmydatabaseyouwillneverfindmyemail";
$text = "[email protected]";
echo "Key : ".$key."<br/>";
echo "Text : ".$text . "<br/>";
echo "Md5 : ".md5($text). "<br/>";
echo "Sha1 : ".sha1($text). "<br/>";



$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH , $key, $text, MCRYPT_MODE_ECB, $iv);
echo "Crypted Data : ".$crypttext."<br>";

$base64 = base64_encode($crypttext);
echo "Encoded Data : ".$base64."<br/>";
$decode =  base64_decode($base64);


$decryptdata = mcrypt_decrypt(MCRYPT_BLOWFISH , $key, $crypttext, MCRYPT_MODE_ECB, $iv);

echo "Decoded Data : ".ereg_replace("?", null ,  $decryptdata); 
//event if i add '?' to the sting to the text it works, I don't know why.

Tenga en cuenta que es solo un concepto. Cualquier mejora en este código sería muy apreciable.

 2
Author: Santosh Linkha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-01 04:29:28

Las contraseñas son para un dispositivo de hardware, por lo que la comprobación contra hashes está fuera de cuestión

Eh? No entiendo. ¿Quieres decir que la contraseña debe ser recuperable?

Como otros han dicho, la extensión mcrypt proporciona acceso a muchas funciones criptográficas, sin embargo, está invitando a sus usuarios a poner todos sus huevos en una canasta, una que será potencialmente un objetivo para los atacantes , y si ni siquiera sabe cómo comenzar a resolver el problema entonces usted está haciendo un flaco favor a sus usuarios. No está en condiciones de entender cómo proteger los datos.

La mayoría de las vulnerabilidades de seguridad no se deben a que el algoritmo subyacente sea defectuoso o inseguro, sino a problemas con la forma en que se usa el algoritmo dentro del código de la aplicación.

Dicho esto, es posible construir un sistema razonablemente seguro.

Solo debe considerar el cifrado asimétrico si tiene un requisito para un usuario para crear un mensaje seguro que sea legible por otro usuario (específico). La razón es que su computacionalmente caro. Si solo desea proporcionar un repositorio para que los usuarios ingresen y recuperen sus propios datos, el cifrado simétrico es adecuado.

Sin embargo, si almacena la clave para descifrar el mensaje en el mismo lugar que el mensaje cifrado (o donde se almacena el mensaje cifrado), el sistema no es seguro. Utilice el mismo token para autenticar al usuario que para el clave de descifrado (o en el caso del cifrado asimétrico, utilice el token como frase de paso de clave privada). Dado que tendrá que almacenar el token en el servidor donde se lleva a cabo el descifrado al menos temporalmente, es posible que desee considerar el uso de un sustrato de almacenamiento de sesión sin posibilidad de búsqueda, o pasar el token directamente a un demonio asociado con la sesión que almacenaría el token en memoria y realizaría el descifrado de mensajes a petición.

 2
Author: symcbean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-01 10:33:05

Use password_hash y password_verify

<?php
/**
 * In this case, we want to increase the default cost for BCRYPT to 12.
 * Note that we also switched to BCRYPT, which will always be 60 characters.
 */
$options = [
    'cost' => 12,
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
?>

Y para descifrar:

<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
?>
 1
Author: jvitoroc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-24 22:51:26