使用单个 .pfx 文件的 SSL 客户端:load_cert_chain 中出现错误 [SSL] PEM lib (_ssl.c:3862)

问题描述 投票:0回答:1

我正在尝试使用单个 .pfx 文件进行身份验证创建 SSL 客户端。但是,在Python中使用load_cert_chain时遇到以下错误: [SSL] PEM 库 (_ssl.c:3862)

我正在从 .pfx 文件加载私钥和证书并将其转换为 PEM 格式。我希望这种方法能够成功验证客户端身份,但我不断收到此错误。这是我正在使用的代码:

import ssl
import tempfile
from cryptography.hazmat.primitives.serialization.pkcs12 import 
load_key_and_certificates
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import Encoding, 
PrivateFormat, NoEncryption
with open(pfx_file, 'rb') as f:
    pfx_data = f.read()

private_key, certificate, additional_certificates = load_key_and_certificates(
    pfx_data,
    pfx_password.encode(),
    backend=default_backend()
)

pem_private_key = private_key.private_bytes(
    encoding=Encoding.PEM,
    format=PrivateFormat.PKCS8,
    encryption_algorithm=NoEncryption()
)

pem_certificate = certificate.public_bytes(Encoding.PEM)

with tempfile.NamedTemporaryFile(suffix='.pem', delete=False) as certfile, 
     tempfile.NamedTemporaryFile(suffix='.pem', delete=False) as keyfile:
    certfile.write(pem_certificate)
    keyfile.write(pem_private_key)
    context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH)

    context.load_cert_chain(certfile=certfile.name, keyfile=keyfile.name)

我也使用OpenSSL库尝试了以下方法,但遇到了同样的问题: 上下文 = SSL.Context(SSL.TLSv1_2_METHOD)

python ssl openssl cryptography pfx
1个回答
0
投票

您需要刷新两个临时文件的写入缓冲区。 对于如此少量的数据,在上下文关闭或刷新缓冲区之前,内容不会写入磁盘。

with (tempfile.NamedTemporaryFile(suffix='.pem', delete=False) as certfile, 
      tempfile.NamedTemporaryFile(suffix='.pem', delete=False) as keyfile):
    certfile.write(pem_certificate)
    keyfile.write(pem_private_key)
    certfile.flush()
    keyfile.flush()
    context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH)
    context.load_cert_chain(certfile=certfile.name, keyfile=keyfile.name)

如果您设置

delete=True
并尝试从临时文件文件路径读取,则可能会遇到权限错误。 Windows 似乎根本不喜欢这样。 作为解决方法,您可以创建一个临时目录,将文件写入其中,关闭时文件将被删除。

with tempfile.TemporaryDirectory() as certdir:
    certfile = f'{certdir}/cert.pem'
    keyfile = f'{certdir}/key.pem'
    with open(certfile, 'wb') as fp:
        fp.write(pem_certificate)
    with open(keyfile, 'wb') as fp:
        fp.write(pem_private_key)
    context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH)
    context.load_cert_chain(certfile=certfile, keyfile=keyfile)
© www.soinside.com 2019 - 2024. All rights reserved.