从 php 中的 PKCS7 签名中提取证书

Posted

技术标签:

【中文标题】从 php 中的 PKCS7 签名中提取证书【英文标题】:Extract certificate from a PKCS7 signature in php 【发布时间】:2013-09-13 02:19:08 【问题描述】:

我需要从 pkcs7 签名文件中提取用户证书。我可以使用以下命令通过命令行来完成:

openssl pkcs7 -in somesign.pks7 -inform PEM -print_certs

这将为我提供整个证书链,我可以处理生成的文件以提取我想要的内容。

有没有办法用 openssl_pkcs7_ 命令做到这一点?我看到 openssl_pkcs7_verify 有 $outfilename 将存储证书,但我没有签名的消息,但似乎 $filename 应该有签名和消息,这不是我的情况(签名在单独的文件)。

【问题讨论】:

你不能只从system()调用那个命令行吗 你见过这个问题吗? ***.com/questions/29102564/… 【参考方案1】:

我不知道有一个 php 库为此提供了简单的 API。

我已经实现了几个库,但这可以帮助完成任务。 asn1、crypto-util 和 x509 可通过 composer 获得。

这是从 PKCS7 PEM 文件中提取所有证书的基本概念证明:

<?php

use ASN1\Element;
use ASN1\Type\Constructed\Sequence;
use CryptoUtil\PEM\PEM;
use X509\Certificate\Certificate;

require __DIR__ . "/vendor/autoload.php";

$pem = PEM::fromFile("path-to-your.p7b");
// ContentInfo: https://tools.ietf.org/html/rfc2315#section-7
$content_info = Sequence::fromDER($pem->data());
// SignedData: https://tools.ietf.org/html/rfc2315#section-9.1
$signed_data = $content_info->getTagged(0)->asExplicit()->asSequence();
// ExtendedCertificatesAndCertificates: https://tools.ietf.org/html/rfc2315#section-6.6
$ecac = $signed_data->getTagged(0)->asImplicit(Element::TYPE_SET)->asSet();
// ExtendedCertificateOrCertificate: https://tools.ietf.org/html/rfc2315#section-6.5
foreach ($ecac->elements() as $ecoc) 
    $cert = Certificate::fromASN1($ecoc->asSequence());
    echo $cert->toPEM() . "\n";

ASN.1 处理非常容易出错。我省略了上面示例中的所有完整性检查,但底层库会在错误时抛出异常。

我希望这能提供一些指导,以防有人需要在不依赖外部程序的情况下解析 PKCS #7 结构。

【讨论】:

谢谢,这已经足够接近我想要的了。我将继续使用命令行来处理任何与生产相关的事情(通过 Symfony Process),但出于我的实验目的,这些库将有助于理解和分解该过程。 对于 composer install crypto-util(其中 asn1 是一个依赖项)和 sop/x509:0.5.0 有问题的人,0.6 有依赖项问题。【参考方案2】:

我已经通过exec()函数使用它了。

exec('../../apache/bin/openssl.exe pkcs7 -in D:/mypkcs7.p7b -inform DER -print_certs').

但我认为,最好的选择是使用 SMIME 文件的结构。您可以通过分析 OpenSSL 的源代码来获得结构。找到它可能很难,但是一旦找到它,您就可以在任何地方使用它。 OpenSSL GitHub 源代码可用 here

【讨论】:

以上是关于从 php 中的 PKCS7 签名中提取证书的主要内容,如果未能解决你的问题,请参考以下文章

在 python 中获取 PKCS7 签名者链

SSL证书问题:证书链中的自签名证书

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

通过java读取PKCS7和.p12文件证书信息(subjectDN,vaildstartfrom,ValildTo ..)

是否可以在 iOS 中创建自签名证书?

从jks证书中提取公钥和私钥(jks证书转pem证书)