Python: Lesen eines PKCS12 -Zertifikats mit Pyopensl.Crypto
-
27-10-2019 - |
Frage
Ich habe ein gültiges Zertifikat der spanischen Behörde (FNMT) und möchte damit spielen, um mehr darüber zu erfahren. Die Datei hat eine Erweiterung .p12
Ich möchte die Informationen darin lesen (zuerst und Nachname) und prüfen, ob das Zertifikat gültig ist. Ist es möglich, dies mit Pyopenssl zu tun? Ich denke, ich muss das Crypto -Modul in OpenSSL verwenden. Irgendwelche Hilfe oder nützlichen Link? Versuchen Sie hier zu lesen: http://packages.python.org/pyopensl/opensl-crypto.html Aber nicht viele Informationen :-(
Lösung
Es ist ziemlich einfach zu bedienen. Dies wird nicht getestet, sollte aber funktionieren:
# 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.
Weitere Beispiele werfen Sie einen Blick auf die Unit -Testcode von Pyopenssl. So ziemlich jede Möglichkeit, wie Sie die Bibliothek benutzen möchten, ist da
Andere Tipps
Vielleicht ist es falsch, einem alten Q zu antworten, aber ich dachte, dass es jemandem helfen kann, der dieses Q nach mir findet. Diese Lösung funktioniert für Python 3, und ich denke, es ist ein bisschen besser. Ich fand es in das Repo von Zeep und ist eine Klasse, um die Verwendung zu verkörpern.
Klasse
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)
Verwendungszweck
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)