如何仅用Perl实现基于SHA-256的RSA-OAEP加密?
纯Perl实现RSA-OAEP-SHA256加密的方案
推荐方案:使用Crypt::PK::RSA(CryptX套件)
CryptX是功能完善的Perl加密库,其中的Crypt::PK::RSA模块原生支持RSA-OAEP加密并可指定SHA-256哈希函数,无需调用外部openssl二进制。
安装模块
cpanm Crypt::PK::RSA
或通过CPAN shell安装:
cpan Crypt::PK::RSA
示例代码
use Crypt::PK::RSA; use MIME::Base64; # 加载PEM格式公钥(支持文件路径或直接传入公钥字符串) my $rsa_pub = Crypt::PK::RSA->new('public_key.pem'); # 待加密的密码 my $password = 'your_login_password'; # 执行RSA-OAEP-SHA256加密 # 第二个参数指定填充方式为OAEP,第三个参数指定哈希算法为SHA256 my $encrypted_bytes = $rsa_pub->encrypt($password, 'OAEP', 'SHA256'); # 转换为Base64编码(与WebCrypto API输出格式对齐) my $encrypted_base64 = encode_base64($encrypted_bytes, ''); print $encrypted_base64 . "\n";
备选方案:手动基于Crypt::RSA实现(纯Perl无C依赖)
如果需要完全不依赖C编译模块,可基于Crypt::RSA结合Digest::SHA手动实现OAEP填充逻辑,但这种方式需自行处理填充细节,出错风险较高,仅推荐特殊场景使用。
安装依赖模块
cpanm Crypt::RSA Digest::SHA Crypt::Random
示例代码
use Crypt::RSA; use Crypt::RSA::Key::Public; use Crypt::RSA::Primitives; use Digest::SHA qw(sha256); use MIME::Base64; use Crypt::Random qw(makerandom_octet); # 加载公钥 my $pub_key = Crypt::RSA::Key::Public->new(Filename => 'public_key.pem'); my $prim = Crypt::RSA::Primitives->new(); # 自定义OAEP填充函数(基于SHA256) sub oaep_sha256_encode { my ($message, $modulus_length) = @_; my $hash_len = 32; # SHA256哈希长度为32字节 my $k = int($modulus_length / 8); # 模数对应的字节长度 die "Message too long for RSA-OAEP-SHA256" if length($message) > $k - 2*$hash_len - 2; # 空标签的哈希值 my $l_hash = sha256(''); # 填充字节(0x00) my $ps = "\x00" x ($k - length($message) - 2*$hash_len - 2); # 构造DB段 my $db = $l_hash . $ps . "\x01" . $message; # 生成随机种子 my $seed = makerandom_octet(Length => $hash_len); # MGF1生成DB掩码 my $db_mask = $prim->mgf1($seed, $k - $hash_len - 1, \&sha256); my $masked_db = $db ^ $db_mask; # MGF1生成种子掩码 my $seed_mask = $prim->mgf1($masked_db, $hash_len, \&sha256); my $masked_seed = $seed ^ $seed_mask; return "\x00" . $masked_seed . $masked_db; } # 待加密的密码 my $password = 'your_login_password'; # 获取模数的字节长度 my $modulus_len = $pub_key->n->length_bytes; # 执行OAEP填充 my $encoded_msg = oaep_sha256_encode($password, $modulus_len); # 执行RSA核心加密 my $encrypted_bigint = $prim->core_encrypt($encoded_msg, $pub_key); # 转换为字节流 my $encrypted_bytes = $encrypted_bigint->to_bytes(); # 转换为Base64编码 my $encrypted_base64 = encode_base64($encrypted_bytes, ''); print $encrypted_base64 . "\n";
补充说明
- 优先推荐
Crypt::PK::RSA方案,其实现经过严格测试,稳定性和安全性远高于手动实现。 - 若你的
Crypt::OpenSSL::RSA版本较新,可尝试调用use_sha256_hash()方法后使用encrypt_oaep,但该模块依赖OpenSSL库,不属于纯Perl实现范畴。
内容的提问来源于stack exchange,提问作者zb226
相关产品推荐
相关产品推荐

