使用Perl和OpenSSL验证SMIME签名

时间:2017-09-27 18:51:35

标签: perl openssl smime

我尝试制作一个“手动”验证SMIME消息的Perl脚本。 我真的尝试了很多,但它没有用。

大部分时间验证都会放置 “签名长于钥匙” 或只是给出一个错误的回报。

如果我在控制台上使用OpenSSL,它就像一个魅力。

CER=mycert
KEY=mykey
MSG=msg.txt
PLA=plain.txt

# create keys with:
# openssl req -x509 -nodes -newkey rsa:1024 -keyout mykey -out mycert

echo -n "test" > $PLA

# sign
openssl cms -sign -md sha1 -subject "test" -from "sam"  -to "alice" 
  -signer $CER -inkey $KEY -in $PLA -out $MSG

# verify
openssl smime -verify -purpose any -in $MSG -CAfile $CER 
  -CApath /etc/ssl/certs

>> Verification successful

生成并验证msg.txt

To: alice
From: sam
Subject: test
MIME-Version: 1.0
Content-Type: multipart/signed; protocol="application/pkcs7-signature";     
micalg="sha1"; boundary="----654C4F221B45801BF9249BC8B2EBC320"

This is an S/MIME signed message

------654C4F221B45801BF9249BC8B2EBC320
test
------654C4F221B45801BF9249BC8B2EBC320
Content-Type: application/pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"

MIIEZgYJKoZIhvcNAQcCoIIEVzCCBFMCAQExCTAHBgUrDgMCGjALBgkqhkiG9w0B
BwGgggJfMIICWzCCAcSgAwIBAgIJAJeRsnkW7iHCMA0GCSqGSIb3DQEBCwUAMEUx

我在这里缩短它。

Eep0LlT+ThDmdSWm8OIPA4f5UCI5+jWB91Nf5CqKFhuua2obZmAOqZXcX4E6VdLV
taorGZL0OCiGuUY94QJEdoJZ7rlpkwFBBVE=

------654C4F221B45801BF9249BC8B2EBC320--

现在我尝试用非常简单的Perl来显示它。我简化了它,删除了MIME处理,只使用msg.txt中的内联值。

use strict;
use warnings;
use Crypt::OpenSSL::X509;
use Crypt::OpenSSL::RSA;
use MIME::Base64;

my $in = "msg.txt";
my $crt = "mycert";

my $cert = Crypt::OpenSSL::X509->new_from_file ($crt);
my $pubkey = $cert->pubkey ();
my $rsa = Crypt::OpenSSL::RSA->new_public_key ($pubkey);

my $ct = "test";

my $sig = "MIIEZgYJKoZIhvcNAQcCoIIEVzCCBFMCAQExCTAHBgUrDgMCGjALBgkqhkiG9w0B
BwGgggJfMIICWzCCAcSgAwIBAgIJAJeRsnkW7iHCMA0GCSqGSIb3DQEBCwUAMEUx

我跳过剩下的。它等同于msg.txt

中的签名字符串
Eep0LlT+ThDmdSWm8OIPA4f5UCI5+jWB91Nf5CqKFhuua2obZmAOqZXcX4E6VdLV
taorGZL0OCiGuUY94QJEdoJZ7rlpkwFBBVE=";

$sig = decode_base64 ($sig);   # make it binary
if ($rsa->verify ($ct, $sig))
{
  print "\nverified!\n";
}

# verify fails with "Signature longer than key" or returns false.

我不知道它为什么不起作用。我要感谢任何帮助,谢谢!

1 个答案:

答案 0 :(得分:0)

我建议你使用openssl函数PKCS7_verify()https://github.com/openssl/openssl/blob/master/demos/smime/smver.c#L63

您可以在我当前的项目中查看如何通过FFI将openssl函数直接绑定到perl - https://github.com/0x62ash/crypt-openssl-cms/blob/master/lib/Crypt/OpenSSL/CMS.pm