我拥有由西班牙管理机构(FNMT)颁发的有效证书,我想利用它来学习更多有关该证书的知识。这个文件扩展名为.p12。
我想读取它中的信息(名字和姓氏),并检查证书是否有效。使用pyOpenSSL可以实现吗?我猜我必须使用OpenSSL中的加密模块。是否有任何帮助或有用的链接?尝试在这里阅读:http://packages.python.org/pyOpenSSL/openssl-crypto.html,但没有太多信息 :-(
我拥有由西班牙管理机构(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的单元测试代码。几乎所有你想使用该库的方式都在其中。
由于 pyOpenSSL.crypto.load_pkcs12 已被弃用,以下是使用 cryptography 的等效解决方案,并带有在请求会话中加载的额外奖励。
from cryptography.hazmat.primitives import serialization
from requests import Session
with open("./cert.p12", "rb") as f:
(
private_key,
certificate,
additional_certificates,
) = serialization.pkcs12.load_key_and_certificates(
f.read(), CLIENT_CERT_KEY.encode()
)
# key will be available in user readable temporary file for the time of the
# program run (until key and cert get gc'ed)
key = tempfile.NamedTemporaryFile()
cert = tempfile.NamedTemporaryFile()
key.write(
private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption(),
)
)
key.flush()
cert.write(
certificate.public_bytes(serialization.Encoding.PEM),
)
cert.flush()
session = Session()
session.cert = (cert.name, key.name)
import cryptography.hazmat.primitives.serialization.pkcs12
),否则会出现属性错误(AttributeError: module 'cryptography.hazmat.primitives.serialization' has no attribute 'pkcs12'
)。 - Luisg123v也许回答一个旧问题是错的,但我认为它可能会对在我之后发现这个问题的人有所帮助。这个解决方案适用于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)
p12 = load_pkcs12(open('foo.p12', 'rb').read(), passwd)
我收到了以下信息:OpenSSL.crypto.Error: [('asn1 encoding routines', 'ASN1_get_object', 'header too long')]
- Stanopenssl pkcs12 -noout -info -in foo.p12
,看看输出结果是什么。 - jrialprint(c, p, ca) print('版本', c.get_version()) print('签名算法', c.get_signature_algorithm()) print('序列号:', c.get_serial_number()) print('证书是否过期:', c.has_expired()) print('在此之前无效:', c.get_notBefore()) print('在此之后无效', c.get_notAfter()) #主题名称 subject = c.get_subject() print(subject.get_components()) #签发者名称 suer = x509name = c.get_issuer() print(suer.get_components()) #扩展 print('扩展数:', c.get_extension_count()) print('扩展1:', c.get_extension(0))
- iHTCboy