perl-openssl/perl-Crypt-OpenSSL-AES
GitHub: perl-openssl/perl-Crypt-OpenSSL-AES
为Perl提供OpenSSL AES加密功能的绑定模块,支持多种工作模式及FIPS合规。
Stars: 2 | Forks: 3
# 名称
Crypt::OpenSSL::AES - OpenSSL AES 库的 Perl 封装
# 大纲
```
use Crypt::OpenSSL::AES;
use Crypt::URandom qw( urandom ); # Always use a strong random source
# Basic usage (defaults to AES-ECB based on key length; ECB is not recommended)
my $key = urandom(32);
my $cipher = Crypt::OpenSSL::AES->new($key);
# Recommended usage: AES-256-CBC with proper Initialization Vector and Padding
my $secure_key = urandom(32); # 32 bytes (256 bits) for AES-256
my $iv = urandom(16); # 16 bytes (128 bits) block size for AES
my $secure_cipher = Crypt::OpenSSL::AES->new(
$secure_key,
{
cipher => 'AES-256-CBC',
iv => $iv,
padding => 1, # 1 for standard block padding, 0 for no padding
}
);
my $plaintext = "Confidential data to be encrypted.";
my $encrypted = $secure_cipher->encrypt($plaintext);
my $decrypted = $secure_cipher->decrypt($encrypted);
```
# 描述
该模块实现了对 OpenSSL 的封装。具体来说,它封装了与美国政府高级加密标准(即 Rijndael 算法)相关的方法。原始版本仅支持 AES ECB(电子密码本模式加密)。
该模块与 Crypt::CBC 兼容(可能也与其他利用分组密码来实现流密码的模块兼容)。
该模块是 Crypt::Rijndael 所提供的实现的一种替代方案,后者自行实现了 AES。相比之下,本模块仅仅是对 OpenSSL 库的封装。
从 0.09 版本开始,支持额外的 AES 密码。它们是:
- 分组密码
块大小为 16 字节,如果不是块大小的倍数则必须进行填充。
- AES-128-ECB, AES-192-ECB 和 AES-256-ECB (无 IV)
支持填充
- AES-128-CBC, AES-192-CBC 和 AES-256-CBC
支持填充和 iv
- 流密码
块大小为 1 字节。即使设置了填充(默认设置),OpenSSL 也不会进行填充。
- AES-128-CFB, AES-192-CFB 和 AES-256-CFB
支持 iv
- AES-128-CTR, AES-192-CTR 和 AES-256-CTR
支持 iv
- AES-128-OFB, AES-192-OFB 和 AES-256-OFB
支持 iv
# FIPS 合规性
当使用内置 FIPS 支持的 OpenSSL 3.0+ 时,向构造函数传递 `provider_props =` 'fips=yes'> 以确保仅使用经过 FIPS 验证的算法实现。
**AES-ECB 未被 FIPS 140-3 批准用于通用数据加密。**
请改用带有随机 IV 的 AES-CBC 或 AES-CTR。
```
my $cipher = Crypt::OpenSSL::AES->new($key, {
cipher => 'AES-256-CBC',
iv => $iv,
padding => 1,
provider_props => 'fips=yes',
});
# 运行时检查:
warn "FIPS mode active\n" if Crypt::OpenSSL::AES::fips_mode();
```
# mod\_perl / 多线程环境
**切勿在使用 worker 或 event MPM 的 mod\_perl 环境下将 Crypt::OpenSSL::AES 对象存储在包变量中。** 每个请求处理器必须构造自己的对象。底层的 `EVP_CIPHER_CTX` 不是线程安全的。
在 prefork MPM 下此限制不适用,但您仍应避免在 `use` 阶段(即在 fork 之前的服务器启动时)构造密码对象,因为 OpenSSL 的 PRNG 状态无法在 `fork()` 间安全共享。
mod\_perl 处理程序的推荐模式:
```
sub handler {
my $r = shift;
my $cipher = Crypt::OpenSSL::AES->new($key, { ... });
# use $cipher only within this request
}
# httpd.conf 或 startup.pl
PerlChildInitHandler sub {
Crypt::OpenSSL::AES::post_fork_init();
}
```
- new()
为了与旧版本兼容,您可以简单地将密钥传递给新的构造函数。
# 默认密码是基于密钥大小的 AES-ECB
my $cipher = Crypt::OpenSSL::AES->new($key);
或者
# 密钥大小必须与密码大小匹配
# 16 字节 (128 位) AES-128-xxx
# 24 字节 (192 位) AES-192-xxx
# 32 字节 (256 位) AES-256-xxx
my $cipher = Crypt::OpenSSL::AES->new($key,
{
cipher => 'AES-256-CBC',
iv => $iv, # (支持的密码为 16 字节)
padding => 1, (0 - 无填充, 1 - 填充)
});
# cipher
# AES-128-ECB, AES-192-ECB 和 AES-256-ECB (无 IV)
# AES-128-CBC, AES-192-CBC 和 AES-256-CBC
# AES-128-CFB, AES-192-CFB 和 AES-256-CFB
# AES-128-CTR, AES-192-CTR 和 AES-256-CTR
# AES-128-OFB, AES-192-OFB 和 AES-256-OFB
#
# iv - 16 字节随机数据
# # padding
# 0 - 无填充
# 1 - 填充
- $cipher->encrypt($data)
加密数据。对于分组密码(ECB 和 CBC),`$data` 的大小必须正好是 `blocksize` 的长度(16 字节),**或者**必须在 **new** 构造函数中启用填充,否则此函数将报错。
对于流密码(CFB, CTR 或 OFB),块大小被视为 1 字节,不需要填充。
不再需要 Crypt::CBC 来加密/解密任意长度的数据。
- $cipher->decrypt($data)
解密数据。对于分组密码(ECB 和 CBC),`$data` 的大小必须正好是 `blocksize` 的长度(16 字节),**或者**必须在 **new** 构造函数中启用填充,否则此函数将报错。
对于流密码(CFB, CTR 或 OFB),块大小被视为 1 字节,不需要填充。
不再需要 Crypt::CBC 来加密/解密任意长度的数据。
- $cipher->fips\_mode()
将根据 openssl 'fips=yes' 默认属性是否设置,返回真 (1) 或假 (0)。
- keysize
此方法由 Crypt::CBC 用于验证密钥长度。
该模块实际上支持 16、24 和 32 字节的密钥长度,但为了 Crypt::CBC 的缘故,此方法始终返回 32。
- blocksize
此方法由 Crypt::CBC 用于检查块大小。
AES 的块大小始终为 16 字节。
## 与 CRYPT::CBC 配合使用
由于现在 CBC 密码支持填充,因此不再强制要求使用 Crypt::CBC,但为了向后兼容仍然支持。
```
use Crypt::CBC;
my $plaintext = "This is a test!!";
my $password = "qwerty123";
my $cipher = Crypt::CBC->new(
-key => $password,
-cipher => "Crypt::OpenSSL::AES",
-pbkdf => 'pbkdf2',
);
my $encrypted = $cipher->encrypt($plaintext);
my $decrypted = $cipher->decrypt($encrypted);
```
# 另请参阅
[Crypt::CBC](https://metacpan.org/pod/Crypt%3A%3ACBC)
http://www.openssl.org/
http://en.wikipedia.org/wiki/Advanced\_Encryption\_Standard
http://www.csrc.nist.gov/encryption/aes/
# 缺陷
需要更多(且更好)的测试用例。
# 作者
Tolga Tarhan, <cpan at ttar dot org>
美国政府的高级加密标准即 Rijndael 算法,由 Vincent Rijmen 和 Joan Daemen 开发。
# 版权和许可
Copyright (C) 2006 - 2024 DelTel, Inc.
本库是自由软件;您可以根据 Perl 本身的条款重新分发和/或修改它,无论是 Perl 版本 5.8.5,还是您可选择拥有的任何更高版本的 Perl 5。
标签:AES, AES-128-ECB, AES-256-CBC, CBC, CFB, CPAN, Crypt::OpenSSL::AES, DNS 反向解析, ECB, HTTP工具, Initialization Vector, IV, OpenSSL, Perl, Rijndael, Wrapper, 分组密码, 加密, 安全测试工具, 密码学, 对称加密, 开发库, 手动系统调用, 流密码, 漏洞扫描器, 自动化审计, 解密, 软件包