字符串函数

PHP crypt() 函数

主题:PHP 字符串参考上一页|下一页

说明

crypt() 函数使用单向加密对字符串进行加密。

这个函数需要一个要加密的字符串和一个salt。 salt 参数是可选的。 然而,crypt() 创建一个没有salt的弱哈希。 因此,请确保指定足够强的salt以提高安全性。

此函数使用基于标准 Unix DES 的算法加密字符串。 但是,根据操作系统,也可以使用其他哈希算法,例如 MD5 或 Blowfish。

crypt() 函数支持多种散列类型的操作系统上,以下常量设置为 0 或 1,具体取决于给定类型是否可用:

  • CRYPT_STD_DES – 标准的基于 DES 加密有 2 个字符的 salt,来自字母表 "./0-9A-Za-z"。在 salt 中使用无效的字符将引发函数失败。
  • CRYPT_EXT_DES – 扩展的基于 DES 加密有 9 个字符的 salt,由 1 个下划线,后边跟 4 个字节的迭代次数和 4 个字节的 salt 组成。这些被编码为可打印字符,每个字符 6 位,最低有效字符优先。值 0 到 63 被编码为 "./0-9A-Za-z"。在 salt 中使用无效的字符将引发函数失败。
  • CRYPT_MD5 – MD5 加密有 12 个字符的 salt,以 $1$ 开始。
  • CRYPT_BLOWFISH – Blowfish 加密有一个以 $2a$、$2x$ 或 $2y$ 开始的 salt,一个两位数的 cost 参数 "$",以及来自字母表 "./0-9A-Za-z" 中的 22 个字符。使用字母表以外的字符将引发函数返回一个长度为 0 的字符串。"$" 参数是以 2 为底的基于 Blowfish 散列算法的迭代次数的对数,必须在 04-31 范围内。在该范围以外的值将引发函数失败。
  • CRYPT_SHA256 – SHA-256 哈希,包含 16 个字符的salt,以 $5$ 开头。 如果salt字符串以"rounds=<N>$"开头,则 N 的数值用于指示应该执行多少次散列循环,很像 Blowfish 上的成本参数。 默认轮数为 5000,最小为 1000,最大为 999,999,999。 超出此范围的任何 N 选择都将被截断到最近的限制。
  • CRYPT_SHA512 – SHA-512 哈希,包含以 $6$ 开头的十六个字符的salt。 如果salt字符串以"rounds=<N>$"开头,则 N 的数值用于指示应该执行多少次散列循环,很像 Blowfish 上的成本参数。 默认轮数为 5000,最小为 1000,最大为 999,999,999。 超出此范围的任何 N 选择都将被截断到最近的限制。

下表总结了该函数的技术细节。

返回值: 返回散列字符串或小于 13 个字符的字符串,并保证在失败时与 salt 不同。
版本: PHP 4+

注意:使用 crypt() 函数加密的数据无法解密。 此功能通常用于加密为用户验证目的而保存的密码。 在登录时,用户输入的密码被加密,并与之前加密的密码进行比较,以检查它们是否匹配。


语法

crypt() 函数的基本语法如下:

crypt(string, salt);

下面的例子展示了 crypt() 函数的作用。

<?php
// 设置密码
$password = 'veryweekpassword';

// 获取hash,让salt自动生成
$hashed_password = crypt($password);

// 用户输入密码
$user_input = 'differentpassword';

// 验证密码
if(hash_equals($hashed_password, crypt($user_input, $hashed_password))) {
   echo "Password match!";
} else {
    echo "Password did not match!";
}
?>

注意:您应该将 crypt() 的整个结果作为 salt 值传递给密码比较,以避免使用不同的哈希算法时出现问题。 作为标准,基于 DES 的密码散列使用 2 个字符的 salt,而基于 MD5 的散列使用 12 个字符的 salt。

提示: password_hash() 函数使用强哈希,生成强salt,并自动应用适当的轮次。 password_hash() 是一个简单的 crypt() 包装器,并且与现有的密码哈希兼容。 建议使用 password_hash() 代替。


参数

crypt() 函数接受以下参数。

参数 说明
string 必填。 指定要散列的字符串。
salt 可选。 指定一个salt字符串作为散列的基础。

更多示例

这里有更多示例展示了 crypt() 函数的实际工作原理:

以下示例演示了如何使用此函数与不同的哈希类型。

此外,示例中使用的salt仅用于演示目的。 您应该始终为每个密码生成一个不同的、格式正确的salt。

<?php
// 2 个字符的 salt
if(CRYPT_STD_DES == 1) {
    echo 'Standard DES: ' . crypt('veryweekpassword', 'mj')."<br>";
}

// 下划线开头的 9 个字符 salt
if(CRYPT_EXT_DES == 1) {
    echo 'Extended DES: ' . crypt('veryweekpassword', '_R9..some')."<br>";
}

// 以 $1$ 开头的 12 个字符的 salt
if(CRYPT_MD5 == 1) {
    echo 'MD5: ' . crypt('veryweekpassword', '$1$sillystr$')."<br>";
}

// Salt 以 $2a$ 开头,后跟两位数的成本参数 10
if(CRYPT_BLOWFISH == 1) {
    echo 'Blowfish: ' . crypt('veryweekpassword', '$2a$10$usesomesillystringforsalt$')."<br>";
}

// 16 个字符的 salt,以 $5$ 开头。 默认轮数为 5000
if(CRYPT_SHA256 == 1) {
    echo 'SHA-256: ' . crypt('veryweekpassword', '$5$rounds=5000$usesomesillystringforsalt$')."<br>";
}

// 16 个字符的 salt,以 $6$ 开头。 默认轮数为 5000
if(CRYPT_SHA512 == 1) {
    echo 'SHA-512: ' . crypt('veryweekpassword', '$6$rounds=5000$usesomesillystringforsalt$');
}
?>

上面示例的输出将如下所示:

Standard DES: mjkg7W9MIGLBk
Extended DES: _R9..someX2hbRcR/P46
MD5: $1$sillystr$z0gQGUVSrSbHpcUvF6IvK0
Blowfish: $2a$10$usesomesillystringforez1bDU9TKqvZj.Jlt6Zaw1sTDI55aZsy
SHA-256: $5$rounds=5000$usesomesillystri$HLhfmfXPbeEc3e5CGa.1kHDJ/XLsXoVRXIRS/zUxsl7
SHA-512: $6$rounds=5000$usesomesillystri$nziff29rkNd/Gw8XUi8Ht2.nsxGPiDkBtQ9JYZ4UKMdLyo5lDqCi4lWJxZmw5jKYvWwjLX7WMemTbIS0rSA7l/
Advertisements