password_bcrypt - password_hash php ejemplo




¿Cómo se usa bcrypt para las contraseñas de hash en PHP? (6)

Edit: 2013.01.15 - Si su servidor lo admite, use la solución de martinstoeckli en su lugar.

Todo el mundo quiere hacer esto más complicado de lo que es. La función crypt () hace la mayor parte del trabajo.

function blowfishCrypt($password,$cost)
{
    $chars='./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $salt=sprintf('$2y$%02d$',$cost);
//For PHP < PHP 5.3.7 use this instead
//    $salt=sprintf('$2a$%02d$',$cost);
    //Create a 22 character salt -edit- 2013.01.15 - replaced rand with mt_rand
    mt_srand();
    for($i=0;$i<22;$i++) $salt.=$chars[mt_rand(0,63)];
    return crypt($password,$salt);
}

Ejemplo:

$hash=blowfishCrypt('password',10); //This creates the hash
$hash=blowfishCrypt('password',12); //This creates a more secure hash
if(crypt('password',$hash)==$hash){ /*ok*/ } //This checks a password

Sé que debería ser obvio, pero por favor no use "contraseña" como su contraseña.

De vez en cuando escucho el consejo "Usar bcrypt para almacenar contraseñas en PHP, reglas de bcrypt".

Pero ¿qué es bcrypt ? PHP no ofrece ninguna de estas funciones, Wikipedia balbucea sobre una utilidad de cifrado de archivos y las búsquedas en la Web solo revelan algunas implementaciones de Blowfish en diferentes idiomas. Ahora Blowfish también está disponible en PHP a través de mcrypt , pero ¿cómo ayuda eso con el almacenamiento de contraseñas? Blowfish es un cifrado de propósito general, funciona de dos maneras. Si pudiera estar encriptado, podría ser descifrado. Las contraseñas necesitan una función de hashing unidireccional.

¿Cuál es la explicación?


Entonces, ¿quieres usar bcrypt? ¡Increíble! Sin embargo, al igual que otras áreas de la criptografía, no debería hacerlo usted mismo. Si necesita preocuparse por algo como administrar claves, almacenar sales o generar números aleatorios, lo está haciendo mal.

La razón es simple: es trivialmente fácil arruinar bcrypt . De hecho, si observa casi todos los códigos de esta página, notará que está violando al menos uno de estos problemas comunes.

Enfréntalo, la criptografía es dura.

Dejarlo para los expertos. Déjelo a las personas cuyo trabajo es mantener estas bibliotecas. Si necesitas tomar una decisión, lo estás haciendo mal.

En su lugar, simplemente use una biblioteca. Varios existen en función de sus necesidades.

Bibliotecas

Aquí hay un desglose de algunas de las API más comunes.

API PHP 5.5 - (Disponible para 5.3.7+)

A partir de PHP 5.5, se está introduciendo una nueva API para las contraseñas de hash. También hay una biblioteca de compatibilidad de shim mantenida (por mí) para 5.3.7+. Esto tiene la ventaja de ser una implementación revisada por pares y fácil de usar.

function register($username, $password) {
    $hash = password_hash($password, PASSWORD_BCRYPT);
    save($username, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    if (password_verify($password, $hash)) {
        //login
    } else {
        // failure
    }
}

Realmente, pretende ser extremadamente simple.

Recursos:

Zend \ Crypt \ Password \ Bcrypt (5.3.2+)

Esta es otra API que es similar a la de PHP 5.5 y tiene un propósito similar.

function register($username, $password) {
    $bcrypt = new Zend\Crypt\Password\Bcrypt();
    $hash = $bcrypt->create($password);
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $bcrypt = new Zend\Crypt\Password\Bcrypt();
    if ($bcrypt->verify($password, $hash)) {
        //login
    } else {
        // failure
    }
}

Recursos:

PasswordLib

Este es un enfoque ligeramente diferente para el hashing de contraseñas. En lugar de simplemente admitir bcrypt, PasswordLib admite una gran cantidad de algoritmos de hash. Es principalmente útil en contextos en los que necesita compatibilidad con sistemas heredados y dispares que pueden estar fuera de su control. Es compatible con una gran cantidad de algoritmos de hash. Y es compatible con 5.3.2+

function register($username, $password) {
    $lib = new PasswordLib\PasswordLib();
    $hash = $lib->createPasswordHash($password, '$2y$', array('cost' => 12));
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $lib = new PasswordLib\PasswordLib();
    if ($lib->verifyPasswordHash($password, $hash)) {
        //login
    } else {
        // failure
    }
}

Referencias:

  • Código fuente / documentación: GitHub

PHPASS

Esta es una capa que admite bcrypt, pero también es compatible con un algoritmo bastante fuerte que es útil si no tiene acceso a PHP> = 5.3.2 ... En realidad, es compatible con PHP 3.0+ (aunque no con bcrypt).

function register($username, $password) {
    $phpass = new PasswordHash(12, false);
    $hash = $phpass->HashPassword($password);
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $phpass = new PasswordHash(12, false);
    if ($phpass->CheckPassword($password, $hash)) {
        //login
    } else {
        // failure
    }
}

Recursos

Nota: ¡No use las alternativas de PHPASS que no están alojadas en openwall, son proyectos diferentes!

Acerca de BCrypt

Si se da cuenta, cada una de estas bibliotecas devuelve una sola cadena. Eso es por cómo funciona internamente BCrypt. Y hay un montón de respuestas sobre eso. Aquí hay una selección que he escrito, que no copiaré / pegaré aquí, pero enlazaré a:

Envolver

Hay muchas opciones diferentes. Lo que elijas depende de ti. Sin embargo, le recomendaría ALTAMENTE que use una de las bibliotecas anteriores para manejar esto por usted.

Nuevamente, si está usando crypt() directamente, probablemente esté haciendo algo mal. Si su código usa hash() (o md5() o sha1() ) directamente, definitivamente está haciendo algo mal.

Solo usa una biblioteca ...


Obtendrá mucha información en Suficiente con The Rainbow Tables: lo que necesita saber sobre esquemas de contraseña segura o el marco de hashing de contraseña de PHP portátil .

El objetivo es marcar la contraseña con algo lento, por lo que alguien que obtenga su base de datos de contraseñas morirá al intentar forzar la fuerza bruta (un retraso de 10 ms para verificar una contraseña no es nada para usted, mucho para alguien que intenta forzarla). Bcrypt es lento y se puede usar con un parámetro para elegir qué tan lento es.


Para las contraseñas de OAuth 2 :

$bcrypt = new \Zend\Crypt\Password\Bcrypt;
$bcrypt->create("youpasswordhere", 10)

Puede crear un hash unidireccional con bcrypt utilizando la función crypt() PHP y pasando una sal Blowfish apropiada. Lo más importante de toda la ecuación es que A) el algoritmo no se ha comprometido y B) se le agrega correctamente cada contraseña . No use una sal para toda la aplicación; que abre toda la aplicación para atacar desde un único conjunto de tablas Rainbow.

PHP - Función de cripta


Una alternativa es usar scrypt, específicamente diseñado para ser superior a bcrypt por Colin Percival en su artículo . Hay una extensión de PHP scrypt en PECL . Idealmente, este algoritmo se incluiría en PHP para que se pueda especificar para las funciones password_ * (idealmente como "PASSWORD_SCRYPT"), pero aún no está disponible.





bcrypt