可能重复:
Is MD5 really that bad?
您好,
我正在尝试创建一个相当安全的登录功能。当我使用SQL和PHP将用户插入MySQL表时,我使用md5()函数,但是表格中出现的字母和数字字符串是不是加密且相当安全的方式?
非常感谢一些建议登录功能的好建议。谢谢!
答案 0 :(得分:2)
MD5不是加密,它是哈希。散列函数不是为了反转而设计的,但是假设它的输出是固定长度的,它的输出被认为是相对独特的,所以如果你使用像SHA-1或SHA这样的加密安全密码,它是安全存储密码的好方法。 2(MD5不再具有加密安全性)。
答案 1 :(得分:1)
是的,那是你看到的哈希。如果你正在使用md5()
,请确保至少使用盐。每个用户的可变盐是理想的。
我还建议你研究一下bcrypt。它比其他散列函数慢得多,也更安全。
另一种选择是PHP的crypt功能。
这个SO问题对于某些散列/加密方法有一些答案。您也应该检查一下:How do you use bcrypt for hashing passwords in PHP?
如果您通过HTTP发送用户密码,那么这一切都将是徒劳的。因此,请确保您也设置了HTTPS和SSL。并强制执行强密码! (免责声明 - 有些人反对强制使用强密码,因为它会让用户感到愤怒。你必须自己决定)
答案 2 :(得分:0)
MD5是Hash-Function。它的工作原理是使用一种不容易逆转的数学运算。这是存储密码的好方法。对于登录检查,您只需使用登录表单提供的密码,也可以将MD5功能应用于此,并比较结果。 但是请注意:MD5不再被认为是安全的。请改用SHA-1或其他。
答案 3 :(得分:0)
我认为在撰写本文时尚未明确说明的是,散列函数的使用存在第三方生成预先散列的随机数字和字母或常用密码的大量索引的问题。名。如果你的数据库都被破坏了,那么你肯定会将你的哈希值与这些查找表进行比较,并且可能猜到它们是否在那里。他们所需要的只是管理员密码的一次幸运匹配。
这些预先计算的哈希查找表的术语通常被称为“彩虹表”
通过使用随机字符序列对哈希进行腌制可以有效避免这种情况,因此每个密码都添加了一些内容,从而降低了在查找表中预先计算和索引的可能性。如果需要,可以为每个用户生成这个“盐”。
答案 4 :(得分:0)
MD5哈希值不是哈希密码的最佳方式,它在几年前变得“破碎”(逆向工程)。
只是哈希密码不是理想的安全级别。使用salt,散列和迭代是。这是我通常创建和存储用户密码的方式:
MySQL表:
create table `users` (
`id` int unsigned not null auto_increment,
...all user properties...
`salt` varchar(20) not null,
`pword` blob not null,
primary key(`id`)
) default charset=utf8 collate utf8_unicode_ci;
生成新用户并创建密码:
define('SYSTEM_SALT', 'rgcaeg43cg0#3tg_..+g3gg3g'); /* A random system wide salt */
define('ITERATIONS', 1000); /* Number of hashing iterations */
define('KEY_LENGTH', 256); /* Length of the generated hash */
...
$user = new User();
$salt = PBKDF2::generator(15); /* Salt length is 15 characters */
$pword = PBKDF2::generator(8); /* User password length is 8 characters */
$hashed_pword = PBKDF2::run($pword, SYSTEM_SALT . $salt, ITERATIONS, KEY_LENGTH, PBKDF2::SHA512);
$user->setPassword($hashed_pword);
$user->setSalt($salt);
/* Set the rest of the user properties */
最后,魔术发生的地方,PBKDF2类实现:
class PBKDF2 {
const SHA256 = 'sha256';
const SHA512 = 'sha512';
const TIGER = 'tiger192,4';
const RIPEMD = 'ripemd256';
const HAVAL = 'haval256,5';
public static function run($password, $salt, $iterations, $key_length, $algorithm) {
if (!PBKDF2::isAlgorithmAvailable($algorithm))
throw new PBKDF2Exception("Algorithm not available on your system");
$key_blocks = ceil($key_length / strlen(hash($algorithm, null, true)));
$derived_key = '';
for ($block = 1; $block <= $key_blocks; $block++) {
$current = $initial = hash_hmac($algorithm, $salt . pack('N', $block), $password, true);
for ($i = 1; $i < $iterations; $i++) {
$current ^= ($initial = hash_hmac($algorithm, $initial, $password, true));
}
$derived_key .= $current;
}
return substr($derived_key, 0, $key_length);
}
public static function isAlgorithmAvailable($algorithm) {
return in_array($algorithm, hash_algos());
}
public static function generator($length = 8) {
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789?!_:;,.ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789?!_:;,.';
$buffer = '';
for ($i = 0; $i < intval($length); $i++) {
$buffer .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $buffer;
}
}
PBKDF表示Password Based Key Derivation Function
,是PKCS标准的一部分。上面的类哈希密码1000次(你当然可以更高),PHP中的SHA 512哈希实现(或你的desierable算法)和两个合并的盐。通过这种方式,您应该非常安全地防止彩虹表查找,这是破解散列密码的标准方法。
正如您所看到的,我还为用户生成了密码,这当然可以是非自动生成的,而是让用户选择自己的密码。