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

时间:2013-09-09 14:42:20

标签: php openssl signature pkcs#7 smime

我需要从pkcs7签名文件中提取用户证书。我可以使用以下命令通过命令行执行此操作:

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

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

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

2 个答案:

答案 0 :(得分:3)

我不知道有一个简单的API的PHP库。

我已经实施了几个库,但这可以帮助完成任务。 asn1crypto-utilx509可通过作曲家获得。

这是一个简单的概念证明,它从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结构,而不依赖于外部程序。

答案 1 :(得分:2)

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

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

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