Skip to main content
 首页 » 编程设计

android之pyOpenSSL 的 PKCS7 对象提供的信息非常少,如何在签名中获取公钥的 sha1 摘要

2025年05月04日38freeliver54

我想用 Python 解析 android apk 的 CERT.RSA。 我知道它可以用 pyOpenSSL 解析

import OpenSSL 

cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, open('CERT.RSA', 'rb').read())

cert = OpenSSL.crypto.load_pkcs7_data(type, buffer) 

证书的类型为“OpenSSL.crypto.PKCS7”。

但是现在 PKCS7 对象不完整,我无法获得我需要的属性,是否有其他方法来解析该文件?

请您参考如下方法:

Comments: I don't know if there's a way to convert it to another format so it can be parsed

您可以使用 openssl 将 PKCS#7 转换为 PEM,使用 PyOpenSSL 可以读取 PEM

openssl pkcs7 -print_certs -in sample.p7b -out sample.cer 

Question: ... how can I get the sha1 digest of the public key in the signature

它没有实现,Pull Request 自 2015 年以来就停滞了。
使用 Pull Request 中的代码,您可以做到这一点。

From: GitHub pyca/pyopenssl: implement getters for pkcs#7 certificates, crl's, and data #367

    def get_certificates(self): 
        from OpenSSL.crypto import _lib, _ffi, X509 
        """ 
        https://github.com/pyca/pyopenssl/pull/367/files#r67300900 
 
        Returns all certificates for the PKCS7 structure, if present. Only 
        objects of type ``signedData`` or ``signedAndEnvelopedData`` can embed 
        certificates. 
 
        :return: The certificates in the PKCS7, or :const:`None` if 
            there are none. 
        :rtype: :class:`tuple` of :class:`X509` or :const:`None` 
        """ 
        certs = _ffi.NULL 
        if self.type_is_signed(): 
            certs = self._pkcs7.d.sign.cert 
        elif self.type_is_signedAndEnveloped(): 
            certs = self._pkcs7.d.signed_and_enveloped.cert 
 
        pycerts = [] 
        for i in range(_lib.sk_X509_num(certs)): 
            pycert = X509.__new__(X509) 
            # pycert._x509 = _lib.sk_X509_value(certs, i) 
            # According to comment from @ Jari Turkia 
            # to prevent segfaults use '_lib.X509_dup(' 
            pycert._x509 = _lib.X509_dup(_lib.sk_X509_value(certs, i)) 
            pycerts.append(pycert) 
 
        if not pycerts: 
            return None 
        return tuple(pycerts) 

用法:

pkcs7 = crypto.load_pkcs7_data(crypto.FILETYPE_ASN1, open('signature.der', 'rb').read()) 
certs = get_certificates(pkcs7) 
print(certs) 
for cert in certs: 
    print('digest:{}'.format(cert.digest('sha256'))) 

Output:

(<OpenSSL.crypto.X509 object at 0xf671b62c>, <OpenSSL.crypto.X509 object at 0xf671b86c>) 
digest:b'48:19:A4:2A:56:94:22:14:73:EC:2B:01:45:9E:0B:87:92:44:26:5E:57:AF:59:F5:4C:89:F3:79:83:14:11:A3' 
digest:b'25:BC:AC:86:8F:51:8B:EE:47:CC:8B:A7:78:91:7E:86:09:56:19:4B:B9:C4:10:1B:DF:13:CA:A6:54:E1:F7:4C' 

使用 Python:3.4.2 - OpenSSL:17.1.0 - cryptography:1.9 - cffi:1.10.0 测试


使用

OpenSSL.crypto.load_pkcs7_data(type, buffer) 

Load pkcs7 data from the string buffer encoded with the type type.
The type type must either FILETYPE_PEM or FILETYPE_ASN1).