validar password encriptar encriptada encriptación desencriptar contraseñas contraseña con php mysql pdo

php - password - Insertar hash de contraseña usando declaraciones preparadas PDO



login con contraseña encriptada php (5)

En una inserción básica de mysql puede establecer una variable de contraseña ''PASSWORD ($ password)'' pero esto rompe una declaración PDO.

¿Cómo hash la contraseña al usar pdo :: prepare y pdo :: execute?

$sql= "INSERT INTO contractors (userid, password, name) VALUES (''$userid'', ''$pass1'', ''$name'')"; $result = $dbh->prepare($sql); $count = $result->execute(); Echo $count."<br>";

Soy tan n00b, una simple página de registro me ha llevado dos días. Las respuestas de Kindergarten son bienvenidas.

Gracias,


El uso de sustitución de variables como esa hace que tu aplicación se abra completamente a los ataques de inyección SQL, a menos que estés escapando $ userid y el lote antes del código que pegaste.

Es mejor usar las habilidades de sustitución de PDO (es decir, ya estás llamando .prepare):

$sql = "INSERT INTO contractors (userid, password, name) VALUES (?, PASSWORD(?), ?)"; $query = $dbh->prepare($sql); $dbh->execute(array($userid, $pass1, $name));

No estoy seguro de si la inserción de la CONTRASEÑA () funcionará, corrígeme si me equivoco. Si quiere adoptar el enfoque de Alan y no confiar en MySQL para descifrar sus contraseñas (sabio), también puede hacer algo como esto:

$sql = "INSERT INTO contractors (userid, password, name) VALUES (?, ?, ?)"; $query = $dbh->prepare($sql); $dbh->execute(array($userid, sha1($hashed), $name));

Considera usar una sal también:

$hashed = sha1("SaltedPassword" . $pass1);


Es quizás más seguro si creas tu propio hash (y quizás más simple). La mejor solución, en mi opinión, es crear un hash uniendo varios campos de la tabla, como este:

$pass1 = sha1($pass1.$name);

Nota: md5, como se sugirió anteriormente, no es la mejor solución, ya que actualmente hay muchas bases de datos en Internet con palabras clave asociadas a las variables de hash md5, lo que facilita a alguien que quiera hackear su sistema.


<?php try { $dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = new PDOStatement(); $hash = sha1($pass . $dataUniqueToEachUser); $stmt = $dbh->prepare("INSERT INTO Users(name, email, hash) VALUES (:name, :email, :hash)"); $stmt->bindParam('':name'', $_POST[''username''], PDO::PARAM_STR); $stmt->bindParam('':email'', $_POST[''email''], PDO::PARAM_STR); $stmt->bindParam('':hash'', $hash, PDO::PARAM_STR); $stmt->execute(); if ($stmt->rowCount() == 0) { $valid = true; } } catch (PDOException $e) { echo "An error occurred: {$e}"; } ?>


Nota

Esta respuesta originalmente recomendaba un hash sin sal. Eso es una tontería hoy en día, por lo que ha sido reescrito para llevarlo a la era moderna. Tenga cuidado con las respuestas similares ahora malas en contenido anterior aquí en SO.

Está utilizando PDO, por lo que debería usar consultas parametrizadas con marcadores de posición:

$sql= "INSERT INTO contractors (userid, password, name) VALUES (?, ?, ?)"; $result = $dbh->prepare($sql); $count = $result->execute(array($userid, $pass1, $name)); echo $count."<br>";

En la era moderna, debería usar Blowfish / bcrypt en lugar de MD5 o SHA1. A partir de PHP 5.3, puede usar crypt con el prefijo $2y$ . A partir de PHP 5.5, podrás usar password_hash lugar. Puede usar la biblioteca password_compat de ircmaxell mientras tanto.

Aquí hay una demo que usa crypt y un valor de dificultad muy bajo . Tenga en cuenta que también estamos almacenando la sal. Si bien he codificado la sal aquí en esta demostración, debes usar una sal única por usuario.

$salt = ''saltysaltsaltsalt''; $password_hash = crypt($pass1, ''$2a$07$'' . $salt); $sql= "INSERT INTO contractors (userid, password, salt, name) VALUES (?, ?, ?, ?)"; $result = $dbh->prepare($sql); $count = $result->execute(array($userid, $password_hash, $salt, $name)); echo $count."<br>";

Verificar la contraseña es tan fácil como reconstruir el hash usando los mismos parámetros.

$sth = $dbh->prepare(''SELECT password, salt FROM contractors WHERE userid = ?''); $sth->execute(array($userid)); list($existing_hash, $salt) = $sth->fetch(PDO::FETCH_NUM); unset($sth); $new_hash = crypt($pass1, ''$2a$07$'' . $salt); if($new_hash === $existing_hash) { echo "Password matched."; } else { echo "Password did not match."; }


Si quería hash utilizando MD5, podría hacer lo siguiente con la contraseña antes de construir la declaración SQL:

$pass1 = md5($pass1); $sql = "INSERT INTO contractors ( userid, password, name ) VALUES ( ''$userid'', ''$pass1'', ''$name'' )"; $result = $dbh->prepare($sql); $count = $result->execute(); echo $count."<br>";

La idea es la misma incluso si se trata de otra función hash. Hash la contraseña antes de construir la declaración SQL.

Como Fiarr y VoteyDisciple señalaron en los comentarios a continuación, opte por un hash SHA ya que es más seguro.

sha1 ()