php 散列密码检查无效
php hashed password check not working
我遇到了哈希密码的奇怪问题。我在本网站 (Windows 运行 php) 的另一台服务器 (linux 运行 php) 上使用了来自另一网站的相同脚本.
登录无效,存储的散列密码与输入的密码不匹配,我已经回复检查但他们只是不匹配。
据我所知,代码(两者都相同)适用于 Linux 但不适用于 Windows,这可能吗?
这是代码(两个网站上的代码相同,所以应该不是问题所在)
<?PHP
// get user data
$strUsername = isset($_POST['email']) ? trim(strip_tags($_POST['email'])) : null;
$strPassword = isset($_POST['password']) ? trim(strip_tags($_POST['password'])) : null;
$DBH = new PDO('database details...');
$SQL = "SELECT inj_user_email,inj_user_password,inj_user_password_salt,inj_user_id FROM inj_user WHERE inj_user_email = :username;";
if ( $strUsername == '' || $strPassword = '' )
{
$missing = 'Please enter an email address and password';
}
else
{
$STH = $DBH->prepare($SQL);
$STH->bindParam(':username', $strUsername);
$STH->execute();
$row = $STH->fetch();
if ($STH->rowCount() > 0) {
$verify_password = hash('sha512' , $strPassword.$row['inj_user_password_salt']);
echo $verify_password.'<br>'.$row['inj_user_password'];
if (strcmp($verify_password , $row['inj_user_password']) == 0)
{
session_start();
session_regenerate_id(true);
$_SESSION['user1'] = $row['inj_user_id'];
header('Location: ../screen/');
}
else
{
$missing='Incorrect password';
echo $missing;
exit;
}
}
else
{
$missing ='Email address not found';
}
}
header('Location: ../?missing='.$missing);
?>
谢谢。
您的比较中缺少 =
标志:
if ( $strUsername == '' || $strPassword = '' )
应该是
if ( $strUsername == '' || $strPassword == '' )
此外,该方案使用盐:
$row['inj_user_password_salt']
它在散列之前附加到密码。它来自数据库,所以首先确保正确检索盐并与原始盐匹配。
然后检查您使用的字符编码是否也与原始编码匹配,特别是如果您使用的是非 ascii 字符。 PHP 上最流行的 2 种非 ascii 字符编码是 UTF-8(无 BOM)和 ISO-8859-1。
无论如何,你不应该使用 sha 进行哈希处理(即使是 512 位版本)
有安全的密码散列算法,例如 bcrypt。
PHP >= 5.5 实现了安全密码 hashing/checking 功能 password_hash and password_verify。这就是你应该使用的。
(阅读 PHP 手册中的 FAQ on password hashing 了解更多信息)
还有一些密码哈希库,例如phpass(被流行的 CMS 使用,例如 WordPress 和 Drupal)。
(如果您有兴趣,可以查看我自己的 tweak 以向该库添加对更安全的密码哈希算法的支持)
我遇到了哈希密码的奇怪问题。我在本网站 (Windows 运行 php) 的另一台服务器 (linux 运行 php) 上使用了来自另一网站的相同脚本. 登录无效,存储的散列密码与输入的密码不匹配,我已经回复检查但他们只是不匹配。 据我所知,代码(两者都相同)适用于 Linux 但不适用于 Windows,这可能吗?
这是代码(两个网站上的代码相同,所以应该不是问题所在)
<?PHP
// get user data
$strUsername = isset($_POST['email']) ? trim(strip_tags($_POST['email'])) : null;
$strPassword = isset($_POST['password']) ? trim(strip_tags($_POST['password'])) : null;
$DBH = new PDO('database details...');
$SQL = "SELECT inj_user_email,inj_user_password,inj_user_password_salt,inj_user_id FROM inj_user WHERE inj_user_email = :username;";
if ( $strUsername == '' || $strPassword = '' )
{
$missing = 'Please enter an email address and password';
}
else
{
$STH = $DBH->prepare($SQL);
$STH->bindParam(':username', $strUsername);
$STH->execute();
$row = $STH->fetch();
if ($STH->rowCount() > 0) {
$verify_password = hash('sha512' , $strPassword.$row['inj_user_password_salt']);
echo $verify_password.'<br>'.$row['inj_user_password'];
if (strcmp($verify_password , $row['inj_user_password']) == 0)
{
session_start();
session_regenerate_id(true);
$_SESSION['user1'] = $row['inj_user_id'];
header('Location: ../screen/');
}
else
{
$missing='Incorrect password';
echo $missing;
exit;
}
}
else
{
$missing ='Email address not found';
}
}
header('Location: ../?missing='.$missing);
?>
谢谢。
您的比较中缺少 =
标志:
if ( $strUsername == '' || $strPassword = '' )
应该是
if ( $strUsername == '' || $strPassword == '' )
此外,该方案使用盐:
$row['inj_user_password_salt']
它在散列之前附加到密码。它来自数据库,所以首先确保正确检索盐并与原始盐匹配。
然后检查您使用的字符编码是否也与原始编码匹配,特别是如果您使用的是非 ascii 字符。 PHP 上最流行的 2 种非 ascii 字符编码是 UTF-8(无 BOM)和 ISO-8859-1。
无论如何,你不应该使用 sha 进行哈希处理(即使是 512 位版本)
有安全的密码散列算法,例如 bcrypt。
PHP >= 5.5 实现了安全密码 hashing/checking 功能 password_hash and password_verify。这就是你应该使用的。
(阅读 PHP 手册中的 FAQ on password hashing 了解更多信息)
还有一些密码哈希库,例如phpass(被流行的 CMS 使用,例如 WordPress 和 Drupal)。
(如果您有兴趣,可以查看我自己的 tweak 以向该库添加对更安全的密码哈希算法的支持)