ZetCode

Perl crypt 函数

最后修改于 2025 年 4 月 4 日

Perl 的 crypt 函数执行字符串的单向加密。它主要用于密码存储和验证。

crypt 使用系统的原生加密,通常基于 DES、MD5 或 SHA 算法。该函数需要明文字符串和盐值进行加密。

基本的 crypt 用法

使用 crypt 最简单的方法是提供明文和盐。

basic.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

my $password = "secret123";
my $salt = "ab";

my $encrypted = crypt($password, $salt);
print "Encrypted: $encrypted\n";

我们演示了使用简单的盐对密码进行 crypt 加密。盐会影响加密结果,在实际应用中应随机生成。

$ ./basic.pl
Encrypted: abJnggxhB/yWI

密码验证

crypt 通常用于将输入的密码与存储的哈希值进行验证。

verify.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

my $stored_hash = 'abJnggxhB/yWI';
my $input_pass = 'secret123';

if (crypt($input_pass, $stored_hash) eq $stored_hash) {
    print "Password correct\n";
} else {
    print "Password incorrect\n";
}

此脚本检查输入的密码是否与存储的加密哈希值匹配。存储的哈希值本身用作验证的盐。

$ ./verify.pl
Password correct

生成随机盐

为了安全加密,盐应随机生成。

salt.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

sub generate_salt {
    my @chars = ('.', '/', 0..9, 'A'..'Z', 'a'..'z');
    return join '', @chars[map {rand @chars} 1..8];
}

my $password = "mypassword";
my $salt = generate_salt();
my $hash = crypt($password, $salt);

print "Salt: $salt\n";
print "Hash: $hash\n";

我们从适合 crypt 的字符集中创建一个随机的 8 字符盐。盐与密码结合以创建唯一的哈希。

$ ./salt.pl
Salt: 7dHj9kLm
Hash: 7dHj9kLmXJ4h6Y

MD5 加密

现代系统通常在 crypt 中使用 MD5 加密。

md5.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

my $password = "securepass";
my $salt = '$1$' . join '', map { ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64] } 1..8;

my $hash = crypt($password, $salt);
print "MD5 Hash: $hash\n";

此示例通过使用以 '$1$' 开头的盐来生成 MD5 哈希。结果哈希将比传统的 DES 更长、更安全。

$ ./md5.pl
MD5 Hash: $1$7f8Gj9kL$m4Xp2qR7sT9vYw1z3c5b7

SHA-256/512 加密

为了更强的安全性,可以在 crypt 中使用 SHA-256 或 SHA-512。

sha.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

sub generate_sha_salt {
    my $type = shift || '256'; # 256 or 512
    my $prefix = $type eq '256' ? '$5$' : '$6$';
    return $prefix . join '', map { ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64] } 1..16;
}

my $password = "supersecret";
my $salt = generate_sha_salt('512');
my $hash = crypt($password, $salt);

print "SHA-512 Hash: $hash\n";

我们通过使用以 '$6$' 开头的盐来生成 SHA-512 哈希。SHA 算法提供比旧方法强得多的安全性。

$ ./sha.pl
SHA-512 Hash: $6$7f8Gj9kLm4Xp2qR7$sT9vYw1z3c5b7d9e1f3g5h7j9k1l3m5n7p9q1r3s5t

用户认证系统

这是一个使用 crypt 的完整用户认证示例。

auth.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

my %users = (
    'admin' => '$6$7f8Gj9kL$m4Xp2qR7sT9vYw1z3c5b7d9e1f3g5h',
    'user1' => '$1$7f8Gj9kL$m4Xp2qR7sT9vYw1z3c5b7'
);

print "Username: ";
my $username = <STDIN>;
chomp $username;

print "Password: ";
my $password = <STDIN>;
chomp $password;

if (exists $users{$username} && 
    crypt($password, $users{$username}) eq $users{$username}) {
    print "Authentication successful\n";
} else {
    print "Authentication failed\n";
}

此脚本模拟了一个带有存储哈希的用户认证系统。它展示了与预先计算的哈希值进行正确的密码验证。

密码强度检查器

我们可以将 crypt 与密码强度验证结合起来。

strength.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

sub check_strength {
    my $pass = shift;
    return 0 if length($pass) < 8;
    return 0 unless $pass =~ /[A-Z]/;
    return 0 unless $pass =~ /[a-z]/;
    return 0 unless $pass =~ /[0-9]/;
    return 0 unless $pass =~ /[^A-Za-z0-9]/;
    return 1;
}

print "Enter new password: ";
my $password = <STDIN>;
chomp $password;

if (check_strength($password)) {
    my $salt = '$6$' . join '', map { ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64] } 1..16;
    my $hash = crypt($password, $salt);
    print "Strong password. Hash: $hash\n";
} else {
    print "Password doesn't meet strength requirements\n";
}

此示例在生成安全哈希之前检查密码强度。它强制执行最小长度和字符多样性要求。

最佳实践

来源

Perl crypt 文档

本教程涵盖了 Perl 的 crypt 函数,并提供了实际示例,演示了安全的密码处理技术。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在教授编程方面有超过十年的经验。

列出 所有 Perl 教程