没有正确地重新散列
Not Rehashing Properly
我们有一个 PHP class 可以根据用户凭据读取数据库,根据需要重新哈希 SHA1 => BCrypt。效果很好,但是最近我们正在开发一个 WinForms 应用程序,并且使用 Chilkat BCrypt 程序集,我们注意到重新散列过程有奇怪的效果。
帐号class:
Username/Password 已发送。如果用户有 SHA1,则检查现有行,如果是,我们重新哈希到 BCrypt,否则我们忽略并登录(哈希验证成功)。
现在一切都很好,但是 Chilkat 使用“2a”,而我们的 classes 为最终哈希中的修订写入“2y”。这会阻止登录应用程序和网站!由于重新散列,它是其中之一(都是 bcrypt 散列,从未为我们的测试帐户找到 SHA1)。
因此,我们通过使用 public“生成器”站点生成哈希来了解情况。
我们的代码有问题吗?!
if (is_array($row))
{
if (password_verify($passwd, $row['password']))
{
/* Check if password needs rehashing, if so then continue1 */
//if (password_needs_rehash(sha1($row['password']) , PASSWORD_DEFAULT))
if (preg_match('/^[0-9a-f]{40}$/i', $row['password'])) /* Added for App login, as both hashes are different revisions (2y => 2a) */
{
/* Rehash existing password algorithm to BCRYPT and update */
$newhash = password_hash($passwd, PASSWORD_BCRYPT);
try
{
$stmt = $pdo->prepare("UPDATE users SET password = ?, last_access = NOW(), last_login = NOW() WHERE user_id = ?");
$stmt->execute([$newhash, $row['user_id']]);
}
catch(PDOException $e)
{
/* If there is a PDO exception, throw a STAccountsException exception. */
$STe = new \STAccountsException($e);
$STe->setVarData(['error' => 'Rehash password failed']);
//$STe->setVarData(['query' => 'UPDATE users SET password = ?, last_access = NOW(), last_login = NOW() WHERE user_id = ?', 'values' => [$newhash, $row['user_id']]]);
throw $STe;
}
}
}
我尝试使用
更好地检测哈希
if (preg_match('/^[0-9a-f]{40}$/i', $row['password'])) {}
并且允许在网站和应用程序中登录!然而,SHA1 哈希现在从不重新哈希。这毫无意义,根据我们的数据库记录和用户反馈,这个 class 两年来从未出现过故障。
感谢任何帮助!
更新
这似乎将生成的散列中的“2y”转换为“2a”。这似乎不太合规。
PHP更新:
$hashgenerated = password_hash($passwd, PASSWORD_BCRYPT);
$newhash = str_replace('2y', '2a', mb_substr($hashgenerated, 0, 3)) . mb_substr($hashgenerated, 3);
VB.NET更新:
Dim newString As String = Replace(storedHash, "2y", "2a")
两者做同样的事情,但是 VB.NET 在读取之前动态替换散列并成功登录用户而无需任何密码修改!
一定有更好的方法。现在只是将“2y”替换为“2a”。
改为使用 VB 替换。这只是作为一个中间的“逾越节”,只是它传递了被替换的标识符。它按预期工作,并避免在 PHP 登录端更新用户密码。
Dim newString As String = Replace(storedHash, "2y", "2a")
Dim passwordValid As Boolean = crypt.BCryptVerify(password, newString)
If (passwordValid = True) Then
MsgBox("Hash is valid")
End If
我们有一个 PHP class 可以根据用户凭据读取数据库,根据需要重新哈希 SHA1 => BCrypt。效果很好,但是最近我们正在开发一个 WinForms 应用程序,并且使用 Chilkat BCrypt 程序集,我们注意到重新散列过程有奇怪的效果。
帐号class:
Username/Password 已发送。如果用户有 SHA1,则检查现有行,如果是,我们重新哈希到 BCrypt,否则我们忽略并登录(哈希验证成功)。
现在一切都很好,但是 Chilkat 使用“2a”,而我们的 classes 为最终哈希中的修订写入“2y”。这会阻止登录应用程序和网站!由于重新散列,它是其中之一(都是 bcrypt 散列,从未为我们的测试帐户找到 SHA1)。
因此,我们通过使用 public“生成器”站点生成哈希来了解情况。
我们的代码有问题吗?!
if (is_array($row))
{
if (password_verify($passwd, $row['password']))
{
/* Check if password needs rehashing, if so then continue1 */
//if (password_needs_rehash(sha1($row['password']) , PASSWORD_DEFAULT))
if (preg_match('/^[0-9a-f]{40}$/i', $row['password'])) /* Added for App login, as both hashes are different revisions (2y => 2a) */
{
/* Rehash existing password algorithm to BCRYPT and update */
$newhash = password_hash($passwd, PASSWORD_BCRYPT);
try
{
$stmt = $pdo->prepare("UPDATE users SET password = ?, last_access = NOW(), last_login = NOW() WHERE user_id = ?");
$stmt->execute([$newhash, $row['user_id']]);
}
catch(PDOException $e)
{
/* If there is a PDO exception, throw a STAccountsException exception. */
$STe = new \STAccountsException($e);
$STe->setVarData(['error' => 'Rehash password failed']);
//$STe->setVarData(['query' => 'UPDATE users SET password = ?, last_access = NOW(), last_login = NOW() WHERE user_id = ?', 'values' => [$newhash, $row['user_id']]]);
throw $STe;
}
}
}
我尝试使用
更好地检测哈希if (preg_match('/^[0-9a-f]{40}$/i', $row['password'])) {}
并且允许在网站和应用程序中登录!然而,SHA1 哈希现在从不重新哈希。这毫无意义,根据我们的数据库记录和用户反馈,这个 class 两年来从未出现过故障。
感谢任何帮助!
更新
这似乎将生成的散列中的“2y”转换为“2a”。这似乎不太合规。
PHP更新:
$hashgenerated = password_hash($passwd, PASSWORD_BCRYPT);
$newhash = str_replace('2y', '2a', mb_substr($hashgenerated, 0, 3)) . mb_substr($hashgenerated, 3);
VB.NET更新:
Dim newString As String = Replace(storedHash, "2y", "2a")
两者做同样的事情,但是 VB.NET 在读取之前动态替换散列并成功登录用户而无需任何密码修改!
一定有更好的方法。现在只是将“2y”替换为“2a”。
改为使用 VB 替换。这只是作为一个中间的“逾越节”,只是它传递了被替换的标识符。它按预期工作,并避免在 PHP 登录端更新用户密码。
Dim newString As String = Replace(storedHash, "2y", "2a")
Dim passwordValid As Boolean = crypt.BCryptVerify(password, newString)
If (passwordValid = True) Then
MsgBox("Hash is valid")
End If