在 PHP 中,password_hash() 和 password_verify() 是用于密码加密和验证的函数。它们的配合使用,可以有效地提升密码存储的安全性,防止密码泄露和破解。然而,很多开发者对它们使用的加密算法及其关系仍有疑问,本文将探讨它们的加密算法以及二者之间的关系。
password_hash() 函数是 PHP 5.5 及以上版本引入的,用于将用户的明文密码转化为加密后的密码。它使用了现代的哈希算法(如 bcrypt),并能够自动生成一个“盐”(salt)。盐是一个附加的随机数据,它用于保证相同的明文密码在每次加密时都会生成不同的哈希值。
默认情况下,password_hash() 使用的是 bcrypt 算法,它生成的哈希值包含了盐的内容,因此在存储密码时不需要额外存储盐。bcrypt 算法本身也具备自适应性,即可以通过增加工作因子(cost factor)来增强计算强度,从而抵御暴力破解。
示例代码:
<span><span><span class="hljs-variable">$password</span></span><span> = </span><span><span class="hljs-string">'my_secure_password'</span></span><span>;
</span><span><span class="hljs-variable">$hashedPassword</span></span><span> = </span><span><span class="hljs-title function_ invoke__">password_hash</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>, PASSWORD_BCRYPT);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$hashedPassword</span></span><span>;
</span></span>
password_verify() 函数是用来验证输入的密码是否与存储的哈希值匹配。它的作用是在用户登录时,比较用户输入的明文密码与数据库中存储的加密密码。password_verify() 会自动提取存储的哈希值中的盐,并用同样的算法对用户输入的密码进行加密,然后与存储的哈希值进行比较。
需要注意的是,password_verify() 会根据哈希值中指定的算法进行计算。因此,开发者不需要手动为 password_verify() 传递盐或加密算法,它会根据传入的哈希值自动选择合适的方式进行验证。
示例代码:
<span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">password_verify</span></span><span>(</span><span><span class="hljs-variable">$userInputPassword</span></span><span>, </span><span><span class="hljs-variable">$storedHash</span></span><span>)) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Password is correct!"</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Invalid password!"</span></span><span>;
}
</span></span>
password_hash() 和 password_verify() 的密切关系在于它们使用相同的加密算法进行密码的处理与验证。具体而言:
密码加密: password_hash() 会根据指定的算法(默认是 bcrypt)将明文密码转换为加密后的哈希值。哈希值中包含了盐和算法的其他参数(如工作因子)。
密码验证: password_verify() 通过读取哈希值中的算法信息和盐,使用相同的算法(如 bcrypt)对用户输入的密码进行加密,然后与存储的哈希值进行比较。
因此,password_verify() 必须使用与 password_hash() 完全相同的算法和参数来进行验证。如果哈希值使用了 bcrypt,那么 password_verify() 也会自动使用 bcrypt 进行验证。
虽然 password_hash() 默认为 bcrypt,它也支持其他算法。PHP 7.2 之后,password_hash() 还支持了 argon2i 和 argon2id 两种更强大的算法。argon2 是一种现代化的哈希算法,相比于 bcrypt,它提供了更好的防止 GPU 力量破解的能力。
使用 argon2i 的示例代码:
<span><span><span class="hljs-variable">$hashedPassword</span></span><span> = </span><span><span class="hljs-title function_ invoke__">password_hash</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>, PASSWORD_ARGON2I);
</span></span>
如果密码是使用 argon2 算法加密的,那么 password_verify() 会自动识别并使用相应的算法进行验证。
password_hash() 和 password_verify() 是 PHP 中用于密码加密和验证的两个非常重要的函数。它们的加密算法密切相关,password_hash() 用于加密并生成哈希值,而 password_verify() 用于根据哈希值验证密码的正确性。两者通常配合使用,确保密码存储的安全性。虽然默认情况下使用的是 bcrypt 算法,但 PHP 还支持 argon2 等更强的算法,在需要时可以进行选择。
通过理解 password_hash() 和 password_verify() 使用的加密算法关系,开发者可以更好地设计安全的密码存储和验证机制,提升应用程序的安全性。