在 python 中获取 PKCS7 签名者链

Posted

技术标签:

【中文标题】在 python 中获取 PKCS7 签名者链【英文标题】:Getting PKCS7 signer chain in python 【发布时间】:2016-04-10 01:54:50 【问题描述】:

我有已签名的 PKCS7 消息。它包含一个数据和一个签名证书(具有整个信任链)。

我有一个代码,它使用 m2crypto 从中获取证书。

bio = BIO.MemoryBuffer(pkcs7message)
p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(bio._ptr()))
sk = X509.X509_Stack()
certStack = p7.get0_signers(sk)

它有效。但是,certStack 只返回一个证书(而不是返回整个证书链。

两个问题:

我是否遗漏了什么(可能有一个选项可以让它知道我需要整个链条) 是否有其他方法可以获取整个链(可能是使用 pyopenssl)?

【问题讨论】:

【参考方案1】:

我猜你在签名者和签名者的证书链之间混淆了。 PKCS7_get0_signers 返回签名者列表。

为了构建具有 2 个签名者的 PKCS7 消息,您可以使用以下步骤:

    为第一个签名者构建密钥和证书:

    openssl genrsa -out key1.pem
    openssl req -new -key key1.pem -subj "/CN=key1" | openssl x509 -req -signkey key1.pem -out cert1.pem
    

    为第二个签名者构建密钥和证书:

    openssl genrsa -out key2.pem
    openssl req -new -key key2.pem -subj "/CN=key2" | openssl x509 -req -signkey key2.pem -out cert2.pem
    

    使用两个签名者创建 PKCS7 消息:

    echo "Hello" | openssl smime -sign -nodetach \
      -out signature.der -outform DER \
      -inkey key1.pem -signer cert1.pem -inkey key2.pem -signer cert2.pem 
    

然后可以运行您的 python 脚本打印签名者:

from M2Crypto import *

bio=BIO.File(open('signature.der'))
smime_object = SMIME.PKCS7(m2.pkcs7_read_bio_der(bio._ptr()))    
signers = smime_object.get0_signers(X509.X509_Stack())

for cert in signers:
    print(cert.get_issuer().as_text())

它给出了签名者的发行者:

CN=key1 CN=key2

【讨论】:

我知道签名者和签名者证书链之间的区别。您拥有的代码通常等同于我的代码(提取签名者)。但是,它对证书链没有任何作用。我得到了我的 PKCS7,并且能够使用“openssl pkcs7 print_certs”命令提取链(这表明证书链存储在某处)。一般来说,我的问题是如何从 PKCS7 中提取(在 python 代码中)这些证书链 @VictorRonin 为了获得证书链openssl pkcs7 -print_certs(见pkcs7.c)使用p7->d.sign->certs。这不能直接通过 m2crypto 接口访问,也许可以使用 asn1 解析来检索...

以上是关于在 python 中获取 PKCS7 签名者链的主要内容,如果未能解决你的问题,请参考以下文章

从不透明的 pkcs7 p7m 转换为分离的 smime

使用 OpenSSL 从 SMIME 消息(pkcs7 签名)中提取公共证书

如何使用 openssl 或任何其他在智能卡上签名的库创建 PKCS7 signedData 结构?

java pkcs7格式签名工具

在 C# 中解密和验证 PKCS7 消息

专利学习一种基于聚合签名的联盟链隐私保护方法