Nueva pregunta

Pregunta:

Fecha: 09-03-2015 08:39:45 (En Español)

Cifrar un Password[Resuelta]

En esta ocasion comparto con uds un script que estoy desarrollando.
Estoy haciendo un registro de usuario.
Como los datos de los usuarios son esencialmente importantes y hay que custodiarlos de la mejor manera posible, estoy realizando un script de cifrado.

En el formulario registro tendrá los campos userName, userPass, email.

Trato de cifrar el password ingresado de la manera mas segura posible y luego grabarla en la base de datos.
Para ello establezco 3 puntos

1- El password es irreversible, es decir que no se pueda obtener el password original ingresado por el usuario.
2- Si cifro el mismo password mas de una vez el resultado debe ser distinto.
3- El password cifrado debe ser tan complejo que no sea ininteligible.

Por otra parte, mas adelante me interesa codificar el userName y email, en este caso si debería ser reversible, ya que debo tener el dato real, por lo tanto la lógica seria distinta y aun mas compleja.

Con estos puntos resuelto en la base de datos en los campos username y password solo puedo ver un conjunto de caracteres que a simple vista no tiene sentido alguno.

Aqui el script que estoy desarrollando y que ire mejorandolo.
<?php

header('Content-Type: text/html; charset=UTF-8');

$passwordOriginal = 'admin12345';
$sal =mcrypt_create_iv(22, MCRYPT_DEV_URANDOM);

$passwordSeguro = encriptarPassword($passwordOriginal, $sal);

echo '<b>Password Original:</b> </br>' . $passwordOriginal;
echo '</br></br>';
echo '<b>Password Encriptado:</b> </br>' . $passwordSeguro;
echo '</br></br>';
echo '<hr>';

$sonIguales = verificarPassword($passwordOriginal, $passwordSeguro);

if ($sonIguales) {
    echo '<font color="blue">La contraseña es correcta</font></br>';
} else {
    echo '<font color ="red">La contraseña  es incorrecta</font></br>';
}

echo '<hr>';

// funciones de codificacion

function verificarPassword($passwordIngreso, $passwordSeguro) {
    return password_verify($passwordIngreso, base64_decode("JDJ5JDEyJ" . $passwordSeguro));
}

function encriptarPassword($password, $salt) {

    $passwordEncriptado = codificarPass(hash('sha256', $salt . $password . randomText(rand(5, 20))));
    $passwordEncriptado = base64_encode(password_hash($password, PASSWORD_BCRYPT, array('cost' => 12)));
    $passwordEncriptado = str_replace("JDJ5JDEyJ", "", $passwordEncriptado);
    return $passwordEncriptado;
}

function codificarPass($password, $digito = 7) {
    $set_salt = './1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    $salt = sprintf('$2a$%02d$', $digito);
    for ($i = 0; $i < 22; $i++) {
        $salt .= $set_salt[mt_rand(0, 22)];
    }
    return crypt($password, $salt);
}

function randomText($maxChar) {

    $pattern = "1234567890+-!@$%&/()^_abcdefghijklmnopqrstuvwxyz";
    $key = "";
    for ($i = 0; $i < $maxChar; $i++) {

        $key .= $pattern{rand(0, strlen($pattern) - 1)};
    }

    return $key;
}




Ahora si ejecutamos el script varias veces veremos que cambia el resultado del password cifrado.
Por ejemplo:

ejecuto la primera vez

Password Original:
admin12345

Password Encriptado:
DdNblR5aFB0YjA5RVZZYTB3S3Zzd3V2SHdNdXNrTDMyZHpidHFmRGs2MjNGLzJrUXF4QXQy

Luego refresco la pagina y obtengo:

Password Encriptado:
FJDL053OUtObFh0MnduTmdjV01IS3VHcm5xeW92akhjSkZ3QWJYUkp3dGd1QnhSbEJ5UzJX


Cada vez que refresco es distinto.


Debo aclarar algo Importante sobre el argumento array('cost' => 12)

El cost por defecto es 10 lo modifique a 12

Su valor debe estar comprendido entre 04 y 31.

A mayor numero sea el cost puede que el servidor tarde en responder. Depende de la la potencia del mismo.
La recomendación oficial para elegir el coste más adecuado para un servidor es que el tiempo empleado en codificar una contraseña sea entre 0.1 y 0.5 segundos.

Según la pagina oficial de PHP nos da un ejemplo de como determinar el Cost mas conveniente para el servidor que se este empleando

<?php
/**
 * Este código evaluará el servidor para determinar el coste permitido.
 * Se establecerá el mayor coste posible sin disminuir demasiando la velocidad
 * del servidor. 8-10 es una buena referencia, y más es bueno si los servidores
 * son suficientemente rápidos. El código que sigue tiene como objetivo un tramo de
 * ? 50 milisegundos, que es una buena referencia para sistemas con registros interactivos.
 */
$timeTarget = 0.05; // 50 milisegundos 

$coste = 8;
do {
    $coste++;
    $inicio = microtime(true);
    password_hash("test", PASSWORD_BCRYPT, ["cost" => $coste]);
    $fin = microtime(true);
} while (($fin - $inicio) < $timeTarget);

echo "Coste conveniente encontrado: " . $coste . "\n";
?>



En mi server local de desarrollo por ej

Coste conveniente encontrado: 9

Aunque lo he llevado a 16 y ha tardado unos segundos mas en terminar.
con 12 anda bien.

Cualquier sugerencia es muy bien recibida.

Saludos
Etiquetas: Contraseña - Encriptación - MySQL - PHP - PHP base64 - Pregunta - Seguridad Votos: 3 - Respuestas: 6 - Vistas: 47 Compartir en: Google Facebook Twitter LinkedIn Link
 

Respuestas:

Para participar activamente de la comunidad primero debes autenticarte, ingresa al sistema.Iniciar Sesión
 
frjcbbae garagebible.com