Python: reading a pkcs12 certificate with pyOpenSSL.crypto

后端 未结 2 1357
一整个雨季
一整个雨季 2020-12-03 03:22

I have a valid certificate issued by the spanish authority (FNMT) and I want to play with it to learn more about it. The file has extension .p12

I would like to read

相关标签:
2条回答
  • 2020-12-03 03:51

    Maybe is wrong answering to an old Q, but I thought that it may help someone that find this Q after me. This solution work for python 3, and I think is a little bit better. I found it in the repo of zeep and is a class to encapsule the usage.

    Class

    import os
    from OpenSSL import crypto
    
    class PKCS12Manager():
    
        def __init__(self, p12file, passphrase):
            self.p12file = p12file
            self.unlock = passphrase
            self.webservices_dir = ''
            self.keyfile = ''
            self.certfile = ''
    
            # Get filename without extension
            ext = os.path.splitext(p12file)
            self.filebasename = os.path.basename(ext[0])
    
            self.createPrivateCertStore()
            self.p12topem()
    
        def getKey(self):
            return self.keyfile
    
        def getCert(self):
            return self.certfile
    
        def createPrivateCertStore(self):
            home = os.path.expanduser('~')
            webservices_dir = os.path.join(home, '.webservices')
            if not os.path.exists(webservices_dir):
                os.mkdir(webservices_dir)
            os.chmod(webservices_dir, 0o700)
            self.webservices_dir = webservices_dir
    
        def p12topem(self):
            p12 = crypto.load_pkcs12(open(self.p12file, 'rb').read(), bytes(self.unlock, 'utf-8'))
    
            # PEM formatted private key
            key = crypto.dump_privatekey(crypto.FILETYPE_PEM, p12.get_privatekey())
    
            self.keyfile = os.path.join(self.webservices_dir, self.filebasename + ".key.pem")
            open(self.keyfile, 'a').close()
            os.chmod(self.keyfile, 0o600)
            with open(self.keyfile, 'wb') as f:
                f.write(key)
    
    
            # PEM formatted certificate
            cert = crypto.dump_certificate(crypto.FILETYPE_PEM, p12.get_certificate())
    
            self.certfile = os.path.join(self.webservices_dir, self.filebasename + ".crt.pem")
            open(self.certfile, 'a').close()
            os.chmod(self.certfile, 0o644)
            with open(self.certfile, 'wb') as f:
                f.write(cert)
    

    Usage

    from requests import Session
    from zeep import Client
    from zeep.transports import Transport
    
    # https://github.com/mvantellingen/python-zeep/issues/824
    pkcs12 = PKCS12Manager('cert.p12', 'password_for_cert')
    session = Session()
    session.cert = (pkcs12.getCert(), pkcs12.getKey())
    
    transport = Transport(session=session)
    client = Client('url_service', transport=transport)
    
    0 讨论(0)
  • 2020-12-03 04:08

    It's fairly straight-forward to use. This isn't tested, but should work:

    # load OpenSSL.crypto
    from OpenSSL import crypto
    
    # open it, using password. Supply/read your own from stdin.
    p12 = crypto.load_pkcs12(open("/path/to/cert.p12", 'rb').read(), passwd)
    
    # get various properties of said file.
    # note these are PyOpenSSL objects, not strings although you
    # can convert them to PEM-encoded strings.
    p12.get_certificate()     # (signed) certificate object
    p12.get_privatekey()      # private key.
    p12.get_ca_certificates() # ca chain.
    

    For more examples, have a look through the unit test code of pyopenssl. Pretty much every way you might want to use the library is there

    See also here or without adverts here.

    0 讨论(0)
提交回复
热议问题