更新PHP中存储的旧md5密码以提高安全性
目前,我有一个存储了md5密码的数据库,几年前,这被认为比现在更安全,而且密码需要更安全更新PHP中存储的旧md5密码以提高安全性,php,security,encryption,hash,passwords,Php,Security,Encryption,Hash,Passwords,目前,我有一个存储了md5密码的数据库,几年前,这被认为比现在更安全,而且密码需要更安全 我在这里阅读了很多关于密码> 、代码> MD5、散列、 BCRIPT < /代码>等,并开始考虑沿用下面的一些东西来更好地保护这些密码。 我将使用散列(“sha512”和两种盐的组合,第一种盐是存储在.htaccess等文件中的站点范围的盐,第二种盐将为每个用户创建 下面是一个例子,大致上是我目前正在测试的内容: .htaccess SetEnv SITEWIDE_SALT NeZa5Edabex?26Y#
我在这里阅读了很多关于<代码>密码> <代码>、代码> MD5<代码>、<代码>散列、<代码> BCRIPT < /代码>等,并开始考虑沿用下面的一些东西来更好地保护这些密码。
我将使用散列(“sha512”
和两种盐的组合,第一种盐是存储在.htaccess等文件中的站点范围的盐,第二种盐将为每个用户创建
下面是一个例子,大致上是我目前正在测试的内容:
.htaccess
SetEnv SITEWIDE_SALT NeZa5Edabex?26Y#j5pr7VASpu$8UheVaREj$yA*59t*A$EdRUqer_prazepreTr
example.php
$currentpassword = //get password
$pepper = getenv('SITEWIDE_SALT');
$salt = microtime().ip2long($_SERVER['REMOTE_ADDR']);
$saltpepper = $salt.$pepper;
$password = hash("sha512", md5($currentpassword).$saltpepper);
salt显然需要存储在一个单独的表中,以允许检查将来插入的登录密码,但用户永远不可能看到。您认为这是一种足够的方法吗?不要将
md5
嵌套在sha512
hash中。然后发生md5
冲突也意味着外部哈希中的哈希冲突(因为您正在哈希相同的值!)
存储密码的常用方法是使用以下方案:
<method><separator><salt><separator><hash>
验证密码时,从该字段读取
和
,将其重新应用于密码,然后检查密码是否产生相同的
检查可用的crypt
功能。在现代Linux系统上,crypt
应该能够以合理的方式使用sha512
密码散列:。不要重新发明轮子,你可能只是比md5
更糟糕,除非你是密码散列方面的专家。它将请注意以上方案:Linux标准使用$
作为分隔符,$6$
是sha512
的方法ID,而$2a$
表示您要使用河豚
。因此您甚至可以在数据库中使用多个哈希。md5
哈希的前缀是$1$
(除非您重新发明了md5哈希,否则您的哈希可能不兼容)
认真地说,重新使用现有的
crypt
函数。专家对其进行了充分的检查,它是可扩展的,并且在许多应用程序中都是兼容的。不要将md5
嵌套在sha512
散列中。md5
冲突也意味着外部散列中的散列冲突(因为您正在散列相同的值!)
存储密码的常用方法是使用以下方案:
<method><separator><salt><separator><hash>
验证密码时,从该字段读取
和
,将其重新应用于密码,然后检查密码是否产生相同的
检查可用的crypt
功能。在现代Linux系统上,crypt
应该能够以合理的方式使用sha512
密码散列:。不要重新发明轮子,你可能只是比md5
更糟糕,除非你是密码散列方面的专家。它将请注意以上方案:Linux标准使用$
作为分隔符,$6$
是sha512
的方法ID,而$2a$
表示您要使用河豚
。因此您甚至可以在数据库中使用多个哈希。md5
哈希的前缀是$1$
(除非您重新发明了md5哈希,否则您的哈希可能不兼容)
认真地说,重新使用现有的
crypt
功能。专家对它进行了充分的检查,它可以扩展,并且在许多应用程序中兼容。实现新的、更安全的密码存储应该使用,或者说,这确实是目前最好的解决方案
不要嵌套东西,因为正如@Anony Mouse所描述的那样,由于碰撞,您无法从中获得任何真正的安全性
您可能想做的是实现一个“转换例程”,在该例程中,您的应用程序会在用户登录时将用户从基于MD5的旧系统转换到新的更安全的系统。当登录请求传入时,请查看用户是否在新的更安全的系统中。如果是,请bcrypt/PBKDF2输入密码,进行比较,然后您就可以继续了。如果不是这样的话(一开始没有人),使用旧的基于MD5的系统检查它们。如果匹配(密码正确),则执行密码的bcrypt/PBKDF2转换(因为您现在有了密码),将其存储在新系统中,并删除旧的MD5记录。下次他们登录时,他们在新系统中有一个条目,这样您就可以开始了。一旦所有用户都登录,一旦您实现了此功能,您就可以删除此转换功能,只需对新系统进行身份验证。实现新的、更安全的password存储应该使用or,因为这确实是目前最好的解决方案 不要嵌套东西,因为正如@Anony Mouse所描述的那样,由于碰撞,您无法从中获得任何真正的安全性 您可能想做的是实现一个“转换例程”,在该例程中,您的应用程序会在用户登录时将用户从基于MD5的旧系统转换到新的更安全的系统。当登录请求传入时,请查看用户是否在新的更安全的系统中。如果是,请bcrypt/PBKDF2输入密码,进行比较,然后您就可以继续了。如果不是这样的话(一开始没有人),使用旧的基于MD5的系统检查它们。如果匹配(密码正确),则执行密码的bcrypt/PBKDF2转换(因为您现在有了密码),将其存储在新系统中,并删除旧的MD5记录。下次他们登录时,他们在新系统中有一个条目,因此您可以继续。一旦所有用户都登录,一旦您实施此操作,您就可以删除此tr
function createBlowfishHash($password) {
$salt = to64(getRandomBytes(16));
$salt = '$2a$10$' . $salt;
$result = crypt($password, $salt);
}
function verifyBlowfishHash($password, $hash) {
return $hash == crypt($password, $hash);
}
function migrateMD5Password($md5Hash) {
$salt = to64(getRandomBytes(16));
$salt = '$2a$10$' . $salt;
$hash = crypt($md5Hash, $salt);
return '$md5' . $hash;
}
function checkAndMigrateHash($password, $hash) {
if (substr($hash, 0, 4) == '$md5') {
// Migrate!
$hash = substr($hash, 4);
if (!verifyBlowfishHash(md5($password), $hash) {
return false;
}
// valid hash, so let's generate a new one
$newHash = createBlowfishHash($password);
saveUpdatedPasswordHash($newHash);
return true;
} else {
return verifyBlowfishHash($password, $hash);
}
}
public static function getRandomString($length = 20) {
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$string = '';
for ($i = 0; $i < $length; $i++) {
$string .= substr($characters, (mt_rand() % strlen($characters)), 1);
}
return $string;
}