目前认为MD5是部分不安全的。考虑到这一点,我想知道使用哪种机制来保护密码。

这个问题,“双重哈希”密码是否比只哈希一次更不安全? 建议哈希多次可能是一个好主意,而如何实现个别文件的密码保护?建议使用盐。

我用的是PHP。我想要一个安全快捷的密码加密系统。对一个密码进行一百万次哈希运算可能更安全,但也更慢。如何在速度和安全之间取得良好的平衡?此外,我更希望结果具有恒定数量的字符。

哈希机制必须在PHP中可用 必须是安全的 它可以使用盐(在这种情况下,所有的盐都一样好吗?有没有办法生产出好的盐?)

另外,我是否应该在数据库中存储两个字段(例如,一个使用MD5,另一个使用SHA)?这会让它更安全还是更不安全?

以防我不够清楚,我想知道要使用哪个哈希函数,以及如何选择一个好的盐,以便拥有一个安全和快速的密码保护机制。

没有完全涵盖我的问题的相关问题:

PHP中的SHA和MD5有什么区别 简单密码加密 为asp.net存储密钥和密码的安全方法 如何在Tomcat 5.5中实现加盐密码


当前回答

我使用的是Phpass,这是一个简单的单文件PHP类,可以在几乎每个PHP项目中非常容易地实现。参见The H。

默认情况下,它使用在Phpass中实现的最强可用加密,即bcrypt,并回落到其他加密,直到MD5,以提供向后兼容的框架,如Wordpress。

返回的散列可以按原样存储在数据库中。生成哈希的示例使用如下:

$t_hasher = new PasswordHash(8, FALSE);
$hash = $t_hasher->HashPassword($password);

要验证密码,可以使用:

$t_hasher = new PasswordHash(8, FALSE);
$check = $t_hasher->CheckPassword($password, $hash);

其他回答

好吧 在fitsy,我们需要盐 盐必须是独一无二的 我们来生成它

   /**
     * Generating string
     * @param $size
     * @return string
     */
    function Uniwur_string($size){
        $text = md5(uniqid(rand(), TRUE));
        RETURN substr($text, 0, $size);
    }

我们还需要哈希值 我使用sha512 它是最好的,而且是用PHP编写的

   /**
     * Hashing string
     * @param $string
     * @return string
     */
    function hash($string){
        return hash('sha512', $string);
    }

所以现在我们可以使用这个函数来生成安全的密码

// generating unique password
$password = Uniwur_string(20); // or you can add manual password
// generating 32 character salt
$salt = Uniwur_string(32);
// now we can manipulate this informations

// hashin salt for safe
$hash_salt = hash($salt);
// hashing password
$hash_psw = hash($password.$hash_salt);

现在我们需要在数据库中保存$hash_psw变量值和$salt变量

对于授权,我们将使用相同的步骤…

这是保护客户密码的最好方法……

另外,最后两个步骤你可以使用自己的算法… 但是要确保将来可以生成这个散列密码 当您需要授权用户…

我只想指出,PHP 5.5包含一个密码哈希API,它提供了crypt()的包装器。这个API极大地简化了哈希、验证和重哈希密码哈希的任务。作者还发布了一个兼容性包(以您只需要使用的单个password.php文件的形式),供那些使用PHP 5.3.7及以后版本并希望立即使用它的用户使用。

它目前只支持BCRYPT,但它的目标是轻松扩展到包括其他密码哈希技术,因为技术和成本存储为哈希的一部分,对您首选的哈希技术/成本的更改不会使当前哈希失效,框架将自动地在验证时使用正确的技术/成本。如果您没有显式地定义自己的盐,它还可以处理生成“安全”盐。

API公开了四个函数:

Password_get_info() -返回关于给定散列的信息 Password_hash()—创建密码散列 Password_needs_rehash()—检查给定的散列是否与给定的选项匹配。有用的检查散列是否符合您当前的技术/成本方案,允许您在必要时重新散列 Password_verify()—验证密码是否与散列匹配

目前,这些函数接受PASSWORD_BCRYPT和PASSWORD_DEFAULT密码常量,它们目前是同义词,区别在于PASSWORD_DEFAULT“在支持更新、更强的散列算法的新PHP版本中可能会改变”。在登录时使用PASSWORD_DEFAULT和password_needs_rehash()(并在必要时重新进行散列)应该确保您的散列对暴力攻击具有合理的弹性,几乎不需要做任何工作。

编辑:我刚刚意识到罗伯特·K的回答中简单提到了这一点。我将把这个答案留在这里,因为我认为它提供了更多关于它如何工作的信息,以及它为那些不了解安全性的人提供的易用性。

我通常使用SHA1和salt和用户ID(或其他特定于用户的信息),有时我还使用常数salt(因此我有2部分salt)。

SHA1 is now also considered somewhat compromised, but to a far lesser degree than MD5. By using a salt (any salt), you're preventing the use of a generic rainbow table to attack your hashes (some people have even had success using Google as a sort of rainbow table by searching for the hash). An attacker could conceivably generate a rainbow table using your salt, so that's why you should include a user-specific salt. That way, they will have to generate a rainbow table for each and every record in your system, not just one for your entire system! With that type of salting, even MD5 is decently secure.

需要记住的事情

关于PHP密码加密已经说了很多,其中大多数都是非常好的建议,但是在开始使用PHP进行密码加密之前,请确保您已经实现了以下内容或准备实现以下内容。

服务器

港口

无论您的加密技术有多好,如果您不能正确地保护运行PHP和DB的服务器,那么您所有的努力都是徒劳的。大多数服务器的功能相对相同,它们都有指定的端口,允许您通过ftp或shell远程访问它们。确保您更改了活动的任何远程连接的默认端口。如果不这样做,实际上就使攻击者在访问您的系统时少做了一步。

用户名

在这个世界上,最好不要使用admin、root或类似的用户名。此外,如果你是在一个基于unix的系统上,不要让根帐户登录可访问,它应该总是只有sudo。

密码

你告诉你的用户要设置好的密码以避免被黑客攻击,你也要这么做。当后门大开着的时候,费劲地锁上前门又有什么意义呢?

数据库

服务器

理想情况下,您希望DB和APPLICATION位于不同的服务器上。由于成本原因,这并不总是可行的,但它确实具有一定的安全性,因为攻击者必须通过两个步骤才能完全访问系统。

USER

始终让您的应用程序拥有自己的帐户来访问DB,并且只给它所需的特权。

然后为您创建一个单独的用户帐户,该帐户不存储在服务器上的任何地方,甚至不存储在应用程序中。

比如总是不要做这个根或类似的东西。

密码

遵循与所有好密码相同的原则。另外,不要在同一系统上的任何SERVER或DB帐户上重复使用相同的密码。

PHP

密码

永远不要在你的数据库中存储密码,而是存储哈希和唯一的盐,我将在后面解释为什么。

哈希

单向哈希!!!!!!!永远不要以一种可以反转的方式哈希密码,哈希值应该是一种方式,这意味着你不反转它们并将它们与密码进行比较,而是以同样的方式哈希输入的密码并比较两个哈希值。这意味着即使攻击者访问了数据库,他也不知道实际的密码是什么,只知道其结果哈希值。这意味着在最糟糕的情况下为用户提供更多的安全性。

有很多不错的散列函数(password_hash, hash等等),但是为了使散列有效,您需要选择一个好的算法。(bcrypt和类似的算法都是不错的算法。)

当哈希速度是关键时,越慢越能抵抗暴力攻击。

哈希中最常见的错误之一是哈希值对用户来说不是唯一的。这主要是因为盐不是唯一产生的。

在散列之前,密码应该始终加盐。Salting在密码中添加一个随机字符串,这样类似的密码在DB中就不会出现相同的密码。然而,如果盐对每个用户都不是唯一的(例如:你使用了硬编码的盐),那么你几乎已经让你的盐变得毫无价值。因为一旦攻击者找到了一个密码盐,他就有了所有密码盐。

当你创建一个salt时,确保它是唯一的密码,然后将完成的散列和salt存储在你的DB中。这将使攻击者在获得访问权限之前必须单独破解每个盐和哈希。这对攻击者来说意味着更多的工作和时间。

用户创建密码

如果用户通过前端创建密码,则意味着必须将密码发送到服务器。这就产生了一个安全问题,因为这意味着未加密的密码将被发送到服务器,如果攻击者能够监听和访问,那么PHP中的所有安全性都是毫无价值的。始终安全地传输数据,这是通过SSL完成的,但即使SSL也不是完美无缺的(OpenSSL的Heartbleed缺陷就是一个例子)。

还要让用户创建一个安全的密码,这很简单,应该一直这样做,用户最终会感激它。

最后,无论你采取什么安全措施,没有什么是100%安全的,保护的技术越先进,攻击就会变得越先进。但是,遵循这些步骤将使您的站点更加安全,并且攻击者更不愿意进行攻击。

下面是一个PHP类,它可以轻松地为密码创建散列和盐

http://git.io/mSJqpw

虽然问题已经回答了,但我只是想重申,用于哈希的盐应该是随机的,而不是像第一个答案中建议的电子邮件地址那样。

更多的解释可以在(archive.org的副本)http://www.pivotalsecurity.com/blog/password-hashing-salt-should-it-be-random/上找到

Recently I had a discussion whether password hashes salted with random bits are more secure than the one salted with guessable or known salts. Let’s see: If the system storing password is compromised as well as the system which stores the random salt, the attacker will have access to hash as well as salt, so whether the salt is random or not, doesn’t matter. The attacker will can generate pre-computed rainbow tables to crack the hash. Here comes the interesting part- it is not so trivial to generate pre-computed tables. Let us take example of WPA security model. Your WPA password is actually never sent to Wireless Access Point. Instead, it is hashed with your SSID (the network name- like Linksys, Dlink etc). A very good explanation of how this works is here. In order to retrieve password from hash, you will need to know the password as well as salt (network name). Church of Wifi has already pre-computed hash tables which has top 1000 SSIDs and about 1 million passwords. The size is of all tables is about 40 GB. As you can read on their site, someone used 15 FGPA arrays for 3 days to generate these tables. Assuming victim is using the SSID as “a387csf3″ and password as “123456″, will it be cracked by those tables? No! .. it cannot. Even if the password is weak, the tables don’t have hashes for SSID a387csf3. This is the beauty of having random salt. It will deter crackers who thrive upon pre-computed tables. Can it stop a determined hacker? Probably not. But using random salts does provide additional layer of defense. While we are on this topic, let us discuss additional advantage of storing random salts on a separate system. Scenario #1 : Password hashes are stored on system X and salt values used for hashing are stored on system Y. These salt values are guessable or known (e.g. username) Scenario#2 : Password hashes are stored on system X and salt values used for hashing are stored on system Y. These salt values are random. In case system X has been compromised, as you can guess, there is a huge advantage of using random salt on a separate system (Scenario #2) . The attacker will need to guess addition values to be able to crack hashes. If a 32 bit salt is used, 2^32= 4,294,967,296 (about 4.2 billion) iterations will can be required for each password guessed.