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

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方法要求的唯一参数。

代码中的两处核心错误

  1. new_private_key方法调用错误

    • 该方法仅接受PEM格式的私钥字符串作为参数,不支持直接传入文件名,也没有密码参数的接口。
    • 要加载带密码的私钥,需要借助Crypt::OpenSSL::BIO来读取并解密私钥文件。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:16:22