这是否使用PDO和准备好的语句正确进行安全登录? [英] Is this using PDO and prepared statements correctly for a secure login?
问题描述
再次寻求有关PHP安全性和登录系统的帮助.想知道我是否在这里正确地做到了.如果我在任何地方都不够具体,请询问,我们将不胜感激.我正试图创建一个安全的登录系统,仅用于学习目的.这是代码:
Once again looking for some help with PHP security and a login system. Wondering if i did this correctly here. If i wasn't specific enough anywhere please ask, Any help is greatly appreciated. I am trying to create a secure login system, just for purposes of learning. here is the code:
require("constants.php");
$DBH = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
function createSalt() {
$length = mt_rand(64, 128);
$salt = '';
for ($i = 0; $i < $length; $i++) {
$salt .= chr(mt_rand(33, 255));
}
return $salt;
}
//Salt function created by ircmaxell
function registerNewUser() {
//Check to see if Username Is In Use//
$q = $DBH->prepare("SELECT id FROM users WHERE username = ?");
$username = filter_var($username, FILTER_SANITIZE_STRING);
$data = array($username);
$q->execute($data);
$row = $q->fetch();
if ($row === false) {
//If Username Is Not Already In Use Insert Data//
$hash = hash('sha256', $pass);
$salt = createSalt();
$hash = hash('sha256', $salt . $hash . $pass); //UPDATED
$data = array($username, $hash, $salt);
$qInsert = $DBH->prepare(
"INSERT INTO users (username, password, salt) values (?, ?, ?)"
);
$qInsert->execute($data); //Inserts User Data Into Table//
}
}
推荐答案
到目前为止看起来还不错.不过,我有三个建议:
That looks good so far. I have three suggestions, though:
- 选择更长的盐
- 请勿分别存储盐和密码摘要
- 如果您的数据库连接未连接到
localhost
,请使用其他数据库连接器:PDO(尚)不支持SSL连接
- Choose a longer salt
- Don't store salt and password digest separately
- If your database connection is not to
localhost
use a different database connector: PDO doesn't (yet) support SSL connections
编辑:此外,还要验证客户端作为用户名"提供的输入.但是由于您的代码示例只是摘录,所以我想您正在这样做.
Also, validate the input a client provides as a "username". But since your code sample is just an excerpt I guess you're doing that.
编辑#2:当我说不要分别存储盐和密码"时,我的意思是将盐合并到存储的密码哈希中.由于您选择的哈希算法会产生由[0-9a-f]组成的相当长的字符串(64个字符),因此您可能需要考虑生成随机长度的盐(此处为ircmaxell的信用),然后将其连接到开头或密码哈希的末尾.因此,您最终将存储(对局外人而言)无意义的可变长度值(96-128个字符):
EDIT #2: When I said, "don't store salt and password separately" I meant incorporating the salt into the stored password hash. Since the hash algorithm of your choice produces quite a long string (64 character) composed of [0-9a-f] you might want to contemplate generating a salt of random length (credits to ircmaxell here) and either concatenate that to the beginning or end of the password hash. So you'll end up storing variable length values (96 - 128 characters) worth of meaninglessness (to outsiders):
$hash = hash('sha256', $pass);
$salt = substr(hash('sha256', mt_rand(0, 1337)), mt_rand(0, 31), 32);
$hash = $salt . hash('sha256', $salt . $hash . $pass);
这篇关于这是否使用PDO和准备好的语句正确进行安全登录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!