PHP密码的安全哈希和盐

目前据说MD5部分不安全。考虑到这一点,我想知道使用哪种机制进行密码保护。

这个问题,“双哈希”密码比只哈希一次更不安全吗?建议多次散列可能是一个好主意,而如何对单个文件实施密码保护?建议使用盐。

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

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

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

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

相关问题不太涵盖我的问题:

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

253903 次浏览

答:这个答案写于2008年。

从那时起,PHP为我们提供了#0#1,并且自引入以来,它们是推荐的密码散列和检查方法。

答案的理论仍然是一个很好的阅读。

太长别读

不要

  • 不要限制用户可以输入的密码字符。只有白痴才会这样做。
  • 不要限制密码的长度。如果你的用户想要一个超级酷毙宇宙世界霹雳无敌棒的句子,不要阻止他们使用它。
  • 不要删除或转义密码中的超文本标记语言和特殊字符。
  • 永远不要以纯文本形式存储用户密码。
  • 永远不要将密码通过电子邮件发送给您的用户除非他们失去了他们的,你派了一个临时的。
  • 永远不要以任何方式记录密码。
  • 不要使用SHA1或MD5甚至SHA256散列密码!现代饼干可以分别超过60和1800亿哈希/秒。
  • 不要混合bcrypt和hash()的原始输出,要么使用十六进制输出,要么base64_encode它。(这适用于任何可能包含流氓\0的输入,这会严重削弱安全性。)

Dos

  • 使用scrypt当你可以;bcrypt如果你不能。
  • 如果您不能使用bcrypt或scrypt以及SHA2哈希,请使用PBKDF2。
  • 当数据库遭到破坏时,重置每个人的密码。
  • 实现合理的最小8-10个字符长度,加上至少1个大写字母、1个小写字母、一个数字和一个符号。这将提高密码的熵,从而使其更难破解。(有关一些辩论,请参阅“什么是好密码?”部分。)

为什么要哈希密码?

哈希密码背后的目标很简单:通过破坏数据库来防止恶意访问用户帐户。因此,密码哈希的目标是通过花费太多时间或金钱来计算纯文本密码来阻止黑客或破解者。时间/成本是您武器库中最好的威慑因素。

您需要对用户帐户进行良好、健壮的哈希的另一个原因是为您提供足够的时间来更改系统中的所有密码。如果您的数据库遭到破坏,您将需要足够的时间在最少锁定系统,如果不更改数据库中的每个密码。

耶利米·格罗斯曼,Whitehat Security的CTO,在最近的一次密码恢复需要暴力破解他的密码保护后,排名第0:

有趣的是,在这个噩梦中,我学到了很多我不知道的关于密码破解,存储和复杂性的知识。

(强调我的)

密码是什么意思?

。(并不是说我完全同意兰德尔的观点。)

简而言之,熵是指密码中有多少变化。当密码只有小写罗马字母时,只有26个字符。这不是很大的变化。字母数字密码更好,有36个字符。但允许大写和小写,带有符号,大约是96个字符。这比仅仅是字母要好得多。一个问题是,为了让我们的密码令人难忘,我们插入了模式——这减少了熵。哎呀!

密码熵很容易为0。使用全范围的ascii字符(大约96个可输入字符)产生每个字符6.6的熵,对于未来的安全性来说,8个字符的密码仍然太低(52.679位熵)。但好消息是:更长的密码和带有Unicode字符的密码确实会增加密码的熵,使其更难破解。

加密StackExchange网站上有一个关于密码熵的更长的讨论。一个好的谷歌搜索也会出现很多结果。

在评论中,我与@pop的谈话,他指出执行一个X长度的密码策略,有X多个字母、数字、符号等,实际上可以通过使密码方案更可预测来减少熵。我同意。随机性,尽可能真正的随机,总是最安全但最不容易记住的解决方案。

据我所知,制作世界上最好的密码是第二十二条军规。要么不容易记住,太容易预测,太短,Unicode字符太多(在Windows/Mobile设备上很难输入),太长,等等。没有一个密码真的足以满足我们的目的,所以我们必须像保护诺克斯堡一样保护它们。

最佳做法

Bcrypt和scrypt是目前的最佳实践。Scrypt会比bcrypt更好,但是它还没有被Linux /Unix或网络服务器采用为标准,并且还没有发布对其算法的深入评论。但是,算法的未来看起来确实很有希望。如果你正在使用Ruby,有一个scrypt gem可以帮助你,Node.js现在有自己的scrypt包。你可以通过Scrypt扩展或利钠扩展在PHP中使用Scrypt(两者都可以在PECL中使用)。

我强烈建议阅读密码函数的留档,如果你想了解如何使用bcrypt,或者找到自己的包装器,或者使用类似PHPASS的东西来实现更传统的实现。我建议至少12轮bcrypt,如果不是15到18。

当我了解到bcrypt只使用河豚的密钥计划时,我改变了使用bcrypt的想法,具有可变成本机制。后者允许您通过增加河豚已经很昂贵的密钥计划来增加暴力破解密码的成本。

平均做法

PHPASS支持PHP 3.0.18到5.3,所以它几乎可以在任何可以想象的安装上使用-如果您的环境不支持bcrypt,应该使用它。

但是假设您根本不能使用bcrypt或PHPASS。然后呢?

尝试使用你的环境/应用程序/用户感知可以容忍的最大轮数实现PDKBF2。我建议的最低数量是2500轮。此外,如果可以使用hash_hmac(),请确保使用hash_hmac(),以使操作更难复制。

今后的做法

即将到来的PHP 5.5是一个全密码保护库,它抽象了使用bcrypt的任何痛苦。虽然我们大多数人在大多数常见环境中坚持使用PHP 5.2和5.3,尤其是共享主机,但@ircmaxell为即将到来的API构建了一个兼容层,它向下兼容PHP 5.3.7。

密码学回顾和免责声明

实际裂缝哈希密码所需的计算能力不存在。计算机“破解”密码的唯一方法是重新创建它并模拟用于保护它的哈希算法。哈希的速度与其被暴力破解的能力呈线性相关。更糟糕的是,大多数哈希算法可以很容易地并行化以更快地执行。这就是为什么像bcrypt和scrypt这样昂贵的方案如此重要。

你不可能预见到所有的威胁或攻击途径,所以你必须尽最大努力保护你的用户在前面。如果你不这样做,那么你甚至可能会错过你被攻击的事实,直到为时已晚而且你有责任。为了避免这种情况,首先要表现得偏执。攻击你自己的软件(内部)并试图窃取用户凭据,或修改其他用户的帐户或访问他们的数据。如果你不测试系统的安全性,那么除了你自己,你不能责怪任何人。

最后:我不是密码学家,以上所说的只是我的观点,但我碰巧认为这是基于我良好的常识和大量的阅读。记住,尽量多疑,尽量让别人难以入侵你的代码。如果你仍然担心,可以联系白帽黑客或密码学家,看看他们对你的代码/系统有什么看法。

我不会以两种不同的方式存储散列后的密码,因为这样系统至少与使用中最弱的散列算法一样弱。

我通常使用SHA1和带有用户ID的盐(或其他一些特定于用户的信息),有时我还使用常量盐(所以我有两个部分的盐)。

SHA1现在也被认为在某种程度上受到了损害,但程度远低于MD5。通过使用盐(任何盐),你阻止了使用泛型彩虹桌来攻击你的哈希(有些人甚至通过搜索哈希成功地将谷歌用作彩虹表)。可以想象,攻击者可以使用你的盐生成彩虹表,所以这就是为什么你应该包含特定于用户的盐。这样,他们将不得不为你系统中的每一条记录生成彩虹表,而不仅仅是为你的整个系统生成一个!有了这种加盐,即使是MD5也相当安全。

Google表示SHA256可用于PHP。

你绝对应该使用盐。我建议使用随机字节(不要局限于字符和数字)。通常,你选择的时间越长,越安全,速度越慢。我想64字节应该没问题。

在可预见的未来,SHA1和盐应该足够了(当然,这取决于您是为诺克斯堡编写代码还是为购物清单的登录系统编写代码)。如果SHA1对您来说不够好,请使用SHA256

可以说,盐的想法是使哈希结果失去平衡。例如,众所周知,空字符串的MD5哈希值是d41d8cd98f00b204e9800998ecf8427e。因此,如果有足够好的记忆力的人会看到该哈希值并知道它是空字符串的哈希值。但是如果字符串是加盐的(例如,使用字符串“MY_PERSONAL_SALT”),“空字符串”的哈希值(即“MY_PERSONAL_SALT”)将变为aeac2612626724592271634fb14d3ea6,因此不明显可以回溯。我想说的是,使用任何盐比不使用更好。因此,知道其中盐使用并不是太重要。

实际上有这样做的网站-你可以给它一个(md5)哈希,它会吐出一个生成该特定哈希的已知明文。如果你想访问一个存储普通md5哈希的数据库,你为这样一个服务的管理员输入哈希并登录是微不足道的。但是,如果密码被加盐,这样的服务将变得无效。

此外,双哈希通常被认为是不好的方法,因为它减少了结果空间。所有流行的哈希都是固定长度的。因此,你只能有这个固定长度的有限值,结果变得不那么多样化。这可以被视为另一种形式的盐渍,但我不推荐它。

最后,从数学上讲,双哈希没有任何好处。然而,在实践中,它有助于防止基于彩虹表的攻击。换句话说,它没有比盐哈希更多的好处,盐哈希在应用程序或服务器上花费的处理器时间要少得多。

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

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

最近我讨论了用随机位加盐的密码哈希是否比用可猜测或已知盐加盐的密码哈希更安全。让我们看看:

如果存储密码的系统和存储随机盐的系统都被入侵,攻击者将有权访问哈希和盐,所以盐是否随机并不重要。攻击者可以生成预计算的彩虹表来破解哈希。有趣的部分来了——生成预计算表并不是那么简单。让我们以WPA安全模型为例。你的WPA密码实际上从未发送到无线接入点。相反,它是用你的SSID(网络名称——如Linksys、Dlink等)散列的。这里有一个很好的解释是如何工作的。为了从哈希中检索密码,您需要知道密码以及盐(网络名称)。Church of Wifi已经预先计算了哈希表,其中包含前1000个SSID和大约100万个密码。所有表的大小约为40 GB。正如您在他们的网站上看到的,有人使用15个FGPA数组3天来生成这些表。

假设受害者使用SSID为“a387csf3”,密码为“123456”,这些表会破解它吗?不!…它不能。即使密码很弱,这些表也没有SSID a387csf3的哈希值。这就是随机盐的美妙之处。它将阻止那些在预计算表上茁壮成长的破解者。它能阻止一个坚定的黑客吗?可能不会。但是使用随机盐确实提供了额外的防御层。

当我们讨论这个话题时,让我们讨论在单独的系统上存储随机盐的额外优势。

场景#1:密码哈希存储在系统X上,用于哈希的盐值存储在系统Y上。这些盐值是可猜测的或已知的(例如用户名)

场景#2:密码哈希存储在系统X上,用于哈希的盐值存储在系统Y上。这些盐值是随机的。

如果系统X已经被入侵,正如您可以猜测的那样,在单独的系统上使用随机盐有一个巨大的优势(场景#2)。攻击者需要猜测加法值才能破解哈希。如果使用32位盐,每个猜测的密码需要2^32=4,294,967,296(大约42亿)次迭代。

一个更简短和更安全的答案-根本不要编写自己的密码机制,使用一个久经考验的机制。

  • PHP 5.5或更高:password_hash()质量好,是PHP核心的一部分。
  • PHP 4. x(已过时):OpenWall的phpass库比大多数自定义代码要好得多-用于WordPress、Drupal等。

大多数程序员只是不具备在不引入漏洞的情况下安全编写加密相关代码的专业知识。

快速自测:什么是密码拉伸,你应该使用多少次迭代?如果你不知道答案,你应该使用password_hash(),因为密码拉伸现在是密码机制的一个关键特性,因为更快的CPU和使用GPU和FPGA每秒数十亿次的猜测的速度破解密码(使用GPU)。

截至2012年,您可以使用安装在5台台式机上的25个GPU在6小时内破解所有8个字符的Windows密码。这是暴力破解,即枚举和检查每个8个字符的Windows密码,包括特殊字符,而不是字典攻击。使用现代GPU,您当然可以破解更多密码或使用更少的GPU-或者以合理的成本在云中租用GPU几个小时。

还有很多针对Windows密码的彩虹表攻击,在普通CPU上运行,速度非常快。

所有这一切都是因为Windows仍然不加盐也不拉伸的密码,即使在Windows 10。2021年仍然如此。不要犯微软所犯的同样的错误!

另见:

  • 优秀的答案更多关于为什么password_hash()phpass是最好的方法。
  • 好的博客文章为包括bcrypt、scrypt和PBKDF2在内的主要算法提供推荐的“工作因子”(迭代次数)。

我正在使用PhPass,它是一个简单的单文件PHP类,几乎可以在每个PHP项目中轻松实现。另见的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);

我只想指出,PHP 5.5包含一个密码散列API,它提供了一个围绕crypt()的包装器。这个API大大简化了散列、验证和重新散列密码散列的任务。作者还发布了一个兼容包(以单个password.php文件的形式,您只需require即可使用),供那些使用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()(如果需要,还可以重新哈希)应该确保您的哈希能够合理地抵御暴力攻击,对您几乎没有任何帮助。

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

我在这里找到了关于这个问题的完美主题:https://crackstation.net/hashing-security.htm,我想让你从中受益,这是源代码,也提供了对基于时间的攻击的预防。

<?php/** Password hashing with PBKDF2.* Author: havoc AT defuse.ca* www: https://defuse.ca/php-pbkdf2.htm*/
// These constants may be changed without breaking existing hashes.define("PBKDF2_HASH_ALGORITHM", "sha256");define("PBKDF2_ITERATIONS", 1000);define("PBKDF2_SALT_BYTES", 24);define("PBKDF2_HASH_BYTES", 24);
define("HASH_SECTIONS", 4);define("HASH_ALGORITHM_INDEX", 0);define("HASH_ITERATION_INDEX", 1);define("HASH_SALT_INDEX", 2);define("HASH_PBKDF2_INDEX", 3);
function create_hash($password){// format: algorithm:iterations:salt:hash$salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" .  $salt . ":" .base64_encode(pbkdf2(PBKDF2_HASH_ALGORITHM,$password,$salt,PBKDF2_ITERATIONS,PBKDF2_HASH_BYTES,true));}
function validate_password($password, $good_hash){$params = explode(":", $good_hash);if(count($params) < HASH_SECTIONS)return false;$pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]);return slow_equals($pbkdf2,pbkdf2($params[HASH_ALGORITHM_INDEX],$password,$params[HASH_SALT_INDEX],(int)$params[HASH_ITERATION_INDEX],strlen($pbkdf2),true));}
// Compares two strings $a and $b in length-constant time.function slow_equals($a, $b){$diff = strlen($a) ^ strlen($b);for($i = 0; $i < strlen($a) && $i < strlen($b); $i++){$diff |= ord($a[$i]) ^ ord($b[$i]);}return $diff === 0;}
/** PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt* $algorithm - The hash algorithm to use. Recommended: SHA256* $password - The password.* $salt - A salt that is unique to the password.* $count - Iteration count. Higher is better, but slower. Recommended: At least 1000.* $key_length - The length of the derived key in bytes.* $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise.* Returns: A $key_length-byte key derived from the password and salt.** Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt** This implementation of PBKDF2 was originally created by https://defuse.ca* With improvements by http://www.variations-of-shadow.com*/function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false){$algorithm = strtolower($algorithm);if(!in_array($algorithm, hash_algos(), true))die('PBKDF2 ERROR: Invalid hash algorithm.');if($count <= 0 || $key_length <= 0)die('PBKDF2 ERROR: Invalid parameters.');
$hash_length = strlen(hash($algorithm, "", true));$block_count = ceil($key_length / $hash_length);
$output = "";for($i = 1; $i <= $block_count; $i++) {// $i encoded as 4 bytes, big endian.$last = $salt . pack("N", $i);// first iteration$last = $xorsum = hash_hmac($algorithm, $last, $password, true);// perform the other $count - 1 iterationsfor ($j = 1; $j < $count; $j++) {$xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));}$output .= $xorsum;}
if($raw_output)return substr($output, 0, $key_length);elsereturn bin2hex(substr($output, 0, $key_length));}?>

要记住的事情

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

服务器

港口

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

用户名

为了世界上所有的好,不要使用用户名admin、root或类似的东西。此外,如果您在基于unix的系统上,不要让root帐户登录可访问,它应该始终是sudo。

密码

您告诉您的用户制作好密码以避免被黑客入侵,做同样的事情。当后门大开时,尽一切努力锁定前门有什么意义。

数据库

服务器

理想情况下,您希望您的数据库和应用程序在单独的服务器上。由于成本原因,这并不总是可能的,但它确实允许一些安全性,因为攻击者必须通过两个步骤才能完全访问系统。

用户

始终让您的应用程序拥有自己的帐户来访问数据库,并仅授予它所需的权限。

然后为您提供一个单独的用户帐户,该帐户不会存储在服务器上的任何位置,甚至不会存储在应用程序中。

喜欢永远不要让这个根或类似的东西。

密码

遵循与所有好密码相同的指南。也不要在同一系统上的任何SERVER或DB帐户上重复使用相同的密码。

php

密码

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

散列

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

有很多好的散列函数(password_hashhash等),但你需要选择一个好的算法来使散列有效。(

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

散列中最常见的错误之一是散列不是用户唯一的。这主要是因为盐不是唯一生成的。

密码应该在散列之前加盐。加盐会在密码中添加一个随机字符串,这样类似的密码在数据库中就不会出现相同的情况。但是,如果盐不是每个用户唯一的(例如:你使用硬编码的盐),那么你的盐就变得毫无价值了。因为一旦攻击者找出一个密码盐,他就有了所有密码的盐。

当你创建一个盐时,确保它是唯一的密码,然后将完成的哈希和盐都存储在你的数据库中。这样做的目的是让攻击者在获得访问权限之前必须单独破解每个盐和哈希。这意味着攻击者需要更多的工作和时间。

用户创建密码

如果用户通过前端创建密码,则意味着必须将其发送到服务器。这会引发安全问题,因为这意味着未加密的密码正在发送到服务器,并且如果攻击者能够监听和访问您在PHP中的所有安全都毫无价值。始终安全传输数据,这是通过SSL完成的,但即使SSL也不是完美无瑕的(OpenSSL的Heartbleed漏洞就是一个例子)。

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

最后,无论您采取何种安全措施,没有什么是100%安全的,要保护的技术越先进,攻击就会变得越先进。但是,遵循这些步骤将使您的网站更加安全,并且不太容易受到攻击者的攻击。

这是一个PHP类,它可以轻松地为密码创建哈希和盐

http://git.io/mSJqpw

从PHP 5.5开始,PHP具有简单、安全的哈希和验证密码的功能,password_hash()password_verify()

$password = 'anna';$hash = password_hash($password, PASSWORD_DEFAULT);$expensiveHash = password_hash($password, PASSWORD_DEFAULT, array('cost' => 20));
password_verify('anna', $hash); //Returns truepassword_verify('anna', $expensiveHash); //Also returns truepassword_verify('elsa', $hash); //Returns false

当使用password_hash()时,它生成一个随机盐并将其包含在输出的哈希中(以及所使用的成本和算法),然后password_verify()读取该哈希并确定所使用的盐和加密方法,并根据提供的明文密码对其进行验证。

提供PASSWORD_DEFAULT指示PHP使用已安装版本PHP的默认哈希算法。确切地说,这意味着哪种算法将随着时间的推移在未来版本中发生变化,因此它将始终是最强大的可用算法之一。

增加成本(默认为10)使哈希更难以暴力破解,但也意味着生成哈希并针对它们验证密码将为服务器的CPU带来更多工作。

请注意,即使默认哈希算法可能会发生变化,旧的哈希也会继续验证,因为使用的算法存储在哈希中,password_verify()会从中获取。

好的身体虚弱时我们需要盐盐必须是独一无二的所以让我们生成它

   /*** 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变量值和$盐变量

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

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

P. s.对于最后2步,您可以使用自己的算法…但请确保您将来可以生成此散列密码当您需要授权用户时…