当前位置: 首页 > 知识库问答 >
问题:

使用Perl和OpenSSL验证SMIME签名

岳宣
2023-03-14

我尝试制作一个Perl-Script来验证SMIME消息"手动"。我真的试了很多,但没有用。

大多数情况下,验证会放置“签名长于密钥”或只是给出错误的返回。

如果我在控制台用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个答案

堵宏毅
2023-03-14

我建议您使用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

 类似资料:
  • 我正在编写一些代码,试图对一些数据进行签名。在将openssl生成的私钥转换为Java密钥库之后,我将Java签名类与SHA256withRSA一起使用。我试图确认openssl中Java类返回的签名,但由于某些原因,我无法让openssl进行验证。我最终需要在iOS Swift 3中实现这个签名验证,但在找到库之前,我想尝试根据openssl标准检查Java签名。 例如,我从我们的登录服务器得到

  • 我正在尝试验证使用BearSSL在嵌入式设备上使用OpenSSL创建的ECDSA签名。 首先,我使用OpenSSL创建了一个私钥并提取了公钥: 然后我提取了原始公钥: 我有一个,它只包含,并使用以下命令对此进行签名: 现在,它包含ASN1格式的签名,长度如预期的那样为72个字节: 现在到嵌入部分。我首先包括数据、签名和公钥: 此外,出于偏执,我比较了和我的字符串的md5和,然后再进行进一步的快速检

  • 我想创建一个签名并使用openssl验证它。我想有我的签名的十六进制输出。 这是我的密码 我得到这个错误: 如果我在创建签名的过程中删除了-hex,它就可以工作了。

  • 我想验证C中的签名,这是我在Java中签名的随机签名。 以下是我用于签名的Java代码: 现在我想用C验证签名,我需要C代码等于以下Java代码: 到目前为止,我所尝试的: 此方法返回0,但我确信随机是用正确的键签名的,并且该方法需要返回1...我想我的验证用的C代码有问题。也许你们中的一个知道如何做对。 --解决--

  • 我正在尝试使用加密来验证open-ssl签名,这是open-ssl部分: 现在在我的C代码中: 但是我总是收到验证失败的消息

  • 我正在OSX 10.6上使用openssl 1.0.1b的命令行界面。 首先,我创建一个DSA密钥。 接下来,我使用该密钥创建一个自签名证书。 接下来,我使用该证书和密钥创建文件的分离smime签名。 最后,我立即尝试验证相同的文件/签名* 但不知怎的,我失败了。 没有任何东西在改变文件,手动md5哈希在前后匹配,但不知何故签名摘要失败了。有人知道我做错了什么吗? 谢谢。 `*注意,-noveri