加密密码

38

什么是最快且安全的密码加密方式(最好用PHP实现),无论您选择哪种方法,它是否具有可移植性?

换句话说,如果我将来将我的网站迁移到不同的服务器上,我的密码是否仍然有效?

据我所知,我现在正在使用的方法依赖于服务器上安装的库的确切版本。

8个回答

33
如果您正在为登录系统选择加密方法,则速度并非您的朋友。Jeff 与 Thomas Ptacek 就密码问题进行了讨论,结论是应该尽可能使用最慢、最安全的加密方法。
引自Thomas Ptacek的博客:
速度恰恰不是密码哈希函数所需要的。现代密码方案会受到递增式密码破解器的攻击。递增式破解器不会预先计算所有可能的破解密码。它们单独考虑每个密码哈希,并像 PHP 登录页一样通过密码哈希函数输入其字典。类似 Ophcrack 的彩虹表破解器以空间来攻击密码;而 John the Ripper、Crack 和 LC5 等递增式破解器则使用时间:统计和计算。
密码攻击的比赛成绩是破解密码 X 所需的时间。对于彩虹表,这个时间取决于您的表格需要多大以及您能够搜索它有多快。对于递增式破解器,时间取决于您能够使密码哈希函数运行的有多快。
您可以优化密码哈希函数的方式越好,密码哈希函数就越快,您的方案就越弱。MD5 和 SHA1,甚至传统的块密码如DES都是被设计成快速的。MD5、SHA1 和 DES 都是弱密码哈希。在现代CPU上,原始的加密构建块如DES和MD5可以进行比特切片、向量化和并行化,以使密码搜索变得极快。"Game-over FPGA" 实现只需数百美元。

16

我和Peter持有相同观点。开发者似乎不太理解密码学。我们都选择(我也有这个问题)MD5或SHA1,因为它们速度快。最近有人指出来这种做法没有任何道理。我们应该选择一种非常慢的哈希算法。考虑到实际情况,一个繁忙网站每隔多久会对密码进行哈希?每半分钟?服务器用时从0.03秒变成0.8秒又有什么关系呢?但是这种额外的缓慢能够有效地防止各种常见的暴力攻击。

根据我的了解,bcrypt是专门设计用于安全密码哈希的,它基于blowfish算法,并且有许多实现方式。

对于PHP用户,请查看PHP Pass

对于.NET用户,请查看BCrypt.NET


10
应该指出的是,您不想加密密码,而是要对其进行哈希。
加密密码可以被解密,让某人看到密码。哈希是一种单向操作,因此用户的原始密码已经(在密码学上)消失了。
至于应该选择哪个算法-使用当前接受的标准算法:
SHA-256
当您对用户的密码进行哈希时,请确保还将一些其他垃圾与其一起哈希。例如:
密码:password1
盐:PasswordSaltDesignedForThisQuestion
将盐附加到用户的密码中:
String s = HashStringSHA256("password1PasswordSaltDesignedForThisQuestion");

4
SHA-256不是用于密码散列的函数,因此不安全。它可以是散列函数PBKDF2的一部分,但这完全是另一回事。您提供的示例也具有误导性,因为盐值不应该是巧妙的短语,而应该是随机(每个用户一个)的值。 - Brendan Long

7

无论你做什么,都不要编写自己的加密算法。这样做几乎可以保证(除非你是密码学家),算法中会存在缺陷,使其易于破解。


即使你是一名密码学家,它也可能存在缺陷——一个算法要经过多年的审查才能变得“流行”。 - Tom Ritter
1
这太真实了。这让我想起了唐纳德·克努斯(Don Knuth)的一个类似轶事,大意是:很久以前,他试图编写一个随机数生成器,并汇集了尽可能多的模糊操作。最终,他运行了这个巨大的程序,并输出了数字4(可能会在叙述中进行修改)。 - ndkrempel

1

考虑使用bcrypt,它被许多现代框架如laravel所使用。


1

我不一定要求最快的,而是要一个很好的平衡。这段代码正在开发的一些服务器相当慢,用于哈希和存储密码的脚本需要5-6秒才能运行,我已经缩小了问题范围,发现是哈希造成的(如果我注释掉哈希,它可以在1-2秒内运行)。

它不必是最安全的,我现在不是为银行编码,但我肯定不会以明文形式存储密码。


虽然系统已关闭,但您仍应以最安全的方式哈希密码。获取某人银行账户密码的最简单方法是什么?创建一个外观极棒的网站,吸引用户注册。大多数人会使用现有的密码。现在您就有了一个庞大的密码列表。所以,如果我知道这是一种糟糕的实现,那么获取其他人的密码最快的方法将是黑客攻击你的系统。 - Andrew T Finnell

0

在插入数据库时,请使用此函数 Password_harsh($password,PASSWORD_DEFAULT)。当从数据库中选择时,您可以使用函数 if(password_verify($password,$databasePassword)) 将要插入的密码与数据库中的密码进行比较。

}else{
echo "password not correct";
}

这将以安全格式加密密码


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接