使用Crypt :: RSA和Crypt :: RSA :: SS :: PSS验证Perl中的RSA PSS签名时遇到问题

时间:2013-03-31 03:02:18

标签: perl rsa digital-signature public-key-encryption

我无法使用Crypt :: RSA和Crypt :: RSA :: SS :: PSS在Perl中验证PSS签名的签名。

以下是这种情况:

我的设备具有1024位RSA密钥,并使用PSS,SHA1和AES-128对数据进行签名。

我成功提取设备的公钥,将其保存在包含PEM_write_RSA_PUBKEY()的文件中

能够使用RSA_verify_PKCS1_PSS()在C / C ++中验证这一点,并在命令行上使用openssl,如下所示:

echo -n hello | 
openssl dgst -verify pubkey.pem -signature hello.sig -sha1 \
             -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:20

其中:

  • 字符串"你好"是设备签署的缓冲区。
  • " pubkey.pem"是从设备导出的设备的RSA公钥 使用PEM_write_RSA_PUBKEY()。
  • " hello.sig"包含设备生成的二进制(原始)签名。 (由于填充,它是128个字节。)

我尝试使用Crypt :: RSA和Crypt :: RSA :: SS :: PSS在Perl中执行上述操作,并且无法使其工作。

我已经测试了这两个模块,并且能够在生成我自己的密钥时生成并验证Perl中的PSS签名,如下所示:

use Crypt::RSA;
use Crypt::RSA::SS::PSS;

my ($message, $rsa, $pss, $signature, $verify);
my ($public, $private);


 # The message to be encrypted
 #
$message = "hello";


 # Generate RSA key
 #
$rsa = new Crypt::RSA;
($public, $private) = $rsa->keygen( Size => 1024, Filename => "key" );


 # Generate PSS signature
 #
$pss = new Crypt::RSA::SS::PSS;

$signature = $pss->sign ( Message => $message, Key => $private ) || die $pss->errstr;

$verify = $pss->verify ( Message => $message, Key => $public, Signature => $signature ) || die $pss->errstr;

 # $verify returns true, it worked.

因此,我没有创建自己的RSA密钥,而是使用以下内容读取公钥:

  $publicKey = new Crypt::RSA::Key::Public ( Filename => "key.public"  );
  ...
 # I pack the 256 character (128 byte) hex string of the signature
 # that's generated by the device.
  $signature = pack ("H*", '03808458…..73E92'); 

" key.public"包含设备的公钥,转换为十进制字符串,插入" n"由Crypt :: RSA :: Key :: Public。

读取/写入的变量的字段

但我无法通过验证: - (

Methinks我应该能够指出它应该使用SHA1和AES-128(而不是像Blowfish)。
我吠叫错了树吗?

...谢谢

1 个答案:

答案 0 :(得分:0)

不确定如何帮助您,而无法使用您的文件和代码进行测试以进行调试。但是,虽然不是最好的解决方案,但是一个好的工作可能是在Perl中使用系统调用。如果您能够在命令提示符下验证它,您可以选择以这种方式进行检查。第一个是system

my $return_code = system("some command");
# or...
my $return_code = system("command", "some", "args");

当您这样做时,您会收到$return_code中返回的退出代码。如果您在命令提示符下执行的任何操作都会在验证失败时退出并显示错误代码,那么您知道在一切顺利时您会收到0,而在错误时会收到另一个数字。< / p>

分析系统调用答案的其他方法,如果你想用反引号读取实际答案,id:

my $answer = `some system call`;
# or...
my $answer = qx[some system call];

通过这样做,您将捕获系统调用发送给STDOUT的任何内容。如果您还想捕获STDERR,那么您可以使用2>&1或类似的东西在同一个调用中重定向它。在这种情况下,您不会获得返回的退出代码。

根据您使用的方法,您可以使用以下答案:

if ($return_code == 0) {
    print "Verified!";
}
# or...
if ($answer =~ /OpenSSL.*?Verification sucess.*?Signature code:(\d+)/) {
    # I'm just making up stuff here, I don't know the answer of your command!
    print "Verification succesful. Signature code was $1";
}

我希望这会有所帮助。我希望我可以测试你的实际脚本和文件,我可以给你一个纯粹的Perl答案,但这至少应该帮助你前进。

旧金山