Perl Crypt::OpenSSL::RSA加载私钥失败,报错含义不明求解答
使用Crypt::OpenSSL::RSA解密时的参数错误问题
问题描述
尝试通过Crypt::OpenSSL::RSA用公钥加密文件、私钥(手动输入密码)解密,加密程序正常,但解密时出现错误。测试代码如下:
#! /usr/bin/perl use strict; use warnings; use 5.026; use Crypt::OpenSSL::RSA; my $private_key_file = 'private.pem'; my $input_file = shift or exit; die "Input file '$input_file' not found\n" unless -e $input_file; print "Enter passphrase for '$private_key_file': "; my $passphrase = <>; chomp $passphrase; exit unless $passphrase; my $priv_key = Crypt::OpenSSL::RSA->new_private_key( $private_key_file, $passphrase ) or die "Failed to get private key"; my $decrypted = $priv_key->decrypt( $input_file ) or die "Decryption failed"; print "Decrypted text:\n$decrypted\n";
运行后报错:
./pub_decrypt encrypted_text Enter passphrase for 'private.pem': blahblah Usage: Crypt::OpenSSL::RSA::new_private_key(proto, key_string_SV) at ./pub_decrypt line 18, <> line 1.
错误解释与解决方法
关于报错中的proto和key_string_SV
proto:是Perl面向对象调用中的类名(这里就是Crypt::OpenSSL::RSA),属于方法调用的隐含参数,不需要手动传入。key_string_SV:指PEM格式的私钥字符串,而不是私钥文件名,这是new_private_key方法要求的唯一参数。
代码中的两处核心错误
new_private_key方法调用错误- 该方法仅接受PEM格式的私钥字符串作为参数,不支持直接传入文件名,也没有密码参数的接口。
- 要加载带密码的私钥,需要借助
Crypt::OpenSSL::BIO来读取并解密私钥文件。
decrypt方法调用错误- 该方法接受的是加密后的字符串数据,不是文件名,必须先读取加密文件的内容再传入。
修正后的代码
#! /usr/bin/perl use strict; use warnings; use 5.026; use Crypt::OpenSSL::RSA; use Crypt::OpenSSL::BIO; my $private_key_file = 'private.pem'; my $input_file = shift or exit; die "Input file '$input_file' not found\n" unless -e $input_file; print "Enter passphrase for '$private_key_file': "; my $passphrase = <>; chomp $passphrase; exit unless $passphrase; # 加载带密码的私钥 my $bio = Crypt::OpenSSL::BIO->new_file($private_key_file, 'r') or die "Failed to open private key file"; my $rsa = Crypt::OpenSSL::RSA->new(); my $priv_key = $rsa->PEM_read_bio_RSAPrivateKey($bio, undef, sub { return $passphrase }) or die "Failed to load private key (wrong passphrase?): " . Crypt::OpenSSL::RSA->error_string(); $bio->close; # 读取加密文件内容 open my $fh, '<', $input_file or die "Can't open input file: $!"; local $/; my $encrypted_data = <$fh>; close $fh; # 解密 my $decrypted = $priv_key->decrypt($encrypted_data) or die "Decryption failed: " . Crypt::OpenSSL::RSA->error_string(); print "Decrypted text:\n$decrypted\n";
修正说明
- 使用
Crypt::OpenSSL::BIO读取私钥文件,通过PEM_read_bio_RSAPrivateKey处理带密码的私钥,密码通过回调函数安全传入。 - 读取加密文件的全部内容后再调用
decrypt方法,符合方法的参数要求。 - 添加了
Crypt::OpenSSL::RSA->error_string()获取详细错误信息,便于排查问题(比如密码错误、密钥格式不正确等)。
内容的提问来源于stack exchange,提问作者Henry Law
相关产品推荐
相关产品推荐

