创建与 C 库中的 crypt(3) 函数完全相同的摘要字符串(假设您实际拥有一个没有被作为潜在武器而被清除的版本)。
crypt
是一个单向哈希函数。PLAINTEXT 和 SALT 被转换为一个称为摘要的短字符串,该字符串被返回。相同的 PLAINTEXT 和 SALT 将始终返回相同的字符串,但没有(已知)方法可以从哈希中获取原始 PLAINTEXT。PLAINTEXT 或 SALT 的微小变化会导致摘要的巨大变化。
没有解密函数。此函数对于密码学来说并不是那么有用(为此,请在您附近的 CPAN 镜像上查找 Crypt 模块),并且“crypt”这个名字有点用词不当。相反,它主要用于检查两段文本是否相同,而无需传输或存储文本本身。一个例子是检查是否给出了正确的密码。密码的摘要被存储,而不是密码本身。用户输入一个密码,该密码使用与存储的摘要相同的盐进行 crypt
处理。如果两个摘要匹配,则密码正确。
在验证现有摘要字符串时,应使用摘要作为盐(例如 `crypt($plain, $digest) eq $digest`)。用于创建摘要的 SALT 作为摘要的一部分可见。这确保了 crypt
将使用与摘要相同的盐来散列新字符串。这允许您的代码与标准 crypt
和更奇特的实现一起工作。换句话说,不要对返回的字符串本身或 SALT 的字节数做出任何假设。
传统上,结果是一个 13 字节的字符串:盐的前两个字节,后面跟着来自集合 `[./0-9A-Za-z]` 的 11 个字节,并且只有明文的第一个八个字节起作用。但是,替代散列方案(如 MD5)、更高级别的安全方案(如 C2)以及非 Unix 平台上的实现可能会生成不同的字符串。
在选择新的盐时,创建一个随机的两个字符字符串,其字符来自集合 `[./0-9A-Za-z]`(例如 `join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]`)。这组字符只是一个建议;盐中允许的字符完全取决于您系统的 crypt 库,Perl 无法限制 crypt
接受的盐。
以下是一个确保运行该程序的人知道其密码的示例
my $pwd = (getpwuid($<))[1];
system "stty -echo";
print "Password: ";
chomp(my $word = <STDIN>);
print "\n";
system "stty echo";
if (crypt($word, $pwd) ne $pwd) {
die "Sorry...\n";
} else {
print "ok\n";
}
当然,向任何询问您密码的人输入您的密码是不明智的。
crypt
函数不适合散列大量数据,尤其是因为您无法获取回信息。查看 Digest 模块以获取更强大的算法。
如果在 Unicode 字符串(其可能包含代码点大于 255 的字符)上使用 crypt
,Perl 会尝试通过尝试将(字符串的副本)降级回一个八位字节字符串来理解这种情况,然后再调用 crypt
(在该副本上)。如果成功,那就很好。如果没有,crypt
会因 Wide character in crypt
而死亡。
可移植性问题:"crypt" in perlport.