如何从DER格式PKCS #7文件中提取过滤出叶子证书?
如何从PKCS7证书输出中筛选叶子证书?
刚好处理过不少Windows程序签名证书的场景,我来给你捋捋怎么快速把叶子证书从一堆证书里挑出来。
首先得明确叶子证书(也就是终端实体证书)和中间/TSA证书的核心区别,这样不管是用命令自动筛选还是手动找都有数:
- 叶子证书的Subject(使用者)和Issuer(颁发者)肯定不一样,毕竟是CA给它签的;
- 它的Basic Constraints(基本约束)扩展要么没有,要么是
CA:FALSE——中间CA证书会明确标CA:TRUE,因为它要给其他证书签名; - 从Windows可执行文件提取的叶子证书,Extended Key Usage(EKU)里一定会有
Code Signing(代码签名),而TSA证书的EKU是Time Stamping,很好区分。
接下来给你两种实用的方法:
方法1:用命令自动筛选(高效)
直接结合OpenSSL和文本处理工具,一步到位输出叶子证书:
基础版(排除中间CA)
这个命令会把所有不含CA:TRUE的证书挑出来,适合大部分场景:
openssl pkcs7 -inform DER -print_certs -text -in cert.der | awk '/-----BEGIN CERTIFICATE-----/{flag=1;cert=""} flag{cert=cert $0 "\n"} /-----END CERTIFICATE-----/{flag=0; if (cert !~ /CA:TRUE/) print cert}'
原理很简单:把每个证书块单独提取,然后检查里面有没有中间CA特有的CA:TRUE标记,没有的就是叶子证书。
精准版(同时排除TSA证书)
如果你的输出里混了TSA时间戳证书,用这个命令更准确——它只保留有Code Signing扩展且Subject和Issuer不同的证书:
openssl pkcs7 -inform DER -print_certs -text -in cert.der | awk '/-----BEGIN CERTIFICATE-----/{flag=1;cert="";has_code_sign=0;issuer_subject_same=0} flag{cert=cert $0 "\n"; if (/X509v3 Extended Key Usage:/) eku_flag=1; if (eku_flag && /Code Signing/) has_code_sign=1; if (/Subject:/) subj=$0; if (/Issuer:/) iss=$0; if (subj == iss) issuer_subject_same=1} /-----END CERTIFICATE-----/{flag=0; eku_flag=0; if (has_code_sign && !issuer_subject_same) print cert}'
方法2:手动检查(适合少量证书)
如果你的证书数量不多,直接看每个证书的几个关键字段就行:
- 找Basic Constraints:看到
CA:TRUE直接跳过,那是中间CA; - 看Extended Key Usage:找带
Code Signing的,这就是你要的程序签名叶子证书; - 对比Subject和Issuer:两者不一样的才是叶子证书(自签的CA证书两者会相同)。
举个例子,你提到的示例证书里,叶子证书就是那个使用者为CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US的,它的颁发者是另一个CA主体,EKU里明确有Code Signing,基本约束是CA:FALSE,完全符合叶子证书的特征。
内容的提问来源于stack exchange,提问作者Simol
相关产品推荐
相关产品推荐

