You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:50:09