Python: чтение сертификата PKCS12 с pyopenssl.crypto
-
27-10-2019 - |
Вопрос
У меня есть действительный сертификат, выданный испанским органом (FNMT), и я хочу поиграть с ним, чтобы узнать больше об этом. Файл имеет расширение .p12
Я хотел бы прочитать информацию в ней (имя и фамилия) и проверить, действителен ли сертификат. Можно ли это сделать с Pyopenssl? Я думаю, что я должен использовать крипто -модуль в OpenSSL. Любая помощь или полезная ссылка? Попытка прочитать здесь: http://packages.python.org/pyopenssl/openssl-crypto.html Но не так много информации :-(
Решение
Это довольно прямолинейно использовать. Это не тестируется, но должно работать:
# 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. Анкет Практически каждый способ, возможно, захотите использовать библиотеку, есть
Другие советы
Может быть, неправильно ответить на старый Q, но я подумал, что это может помочь кому -то, кто найдет этот Q после меня. Это решение работает для 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)