Python: чтение сертификата pkcs12 с помощью pyOpenSSL.crypto - PullRequest
13 голосов
/ 14 июня 2011

У меня есть действующий сертификат, выданный испанской властью (FNMT), и я хочу поиграть с ним, чтобы узнать о нем больше. Файл имеет расширение .p12

Я хотел бы прочитать информацию в нем (имя и фамилия) и проверить, действителен ли сертификат. Возможно ли это сделать с помощью pyOpenSSL? Я думаю, что я должен использовать криптографический модуль в OpenSSL. Любая помощь или полезная ссылка? Попытка прочесть здесь: http://packages.python.org/pyOpenSSL/openssl-crypto.html но не так много информации: - (

Ответы [ 2 ]

33 голосов
/ 14 июня 2011

Это довольно просто использовать.Это не проверено, но должно работать:

# 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.

. Дополнительные примеры можно найти в коде модульного теста pyopenssl .Практически каждый способ использования библиотеки может быть там

См. Также здесь или без рекламы здесь .

0 голосов
/ 30 апреля 2019

Возможно, неправильно отвечая на старый вопрос, но я подумал, что это может помочь кому-то, кто найдет этот вопрос после меня. Это решение работает для Python 3, и я думаю, что немного лучше. Я нашел его в репозитории zeep и является классом для инкапсуляции использования.

Класс

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)

Использование

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)
...