使用 stringIO 对象作为 ssl key/cert 文件

use stringIO object as ssl key/cert file

我想从环境变量中提取我的 ssl 证书和密钥,而不是将它们存储在文件系统中。但是我 运行 遇到了扭曲 ssl

的障碍
from io import StringIO
from twisted.internet import reactor, task, threads, ssl

key = StringIO()
key.write(os.environ['SSLKEY'])
cert = StringIO()
cert.write(os.environ['SSLCERT'])

contextFactory = ssl.DefaultOpenSSLContextFactory(key, cert)    

给我以下异常

2018-04-03 16:01:28-0500 [-] TypeError: Path must be represented as bytes or unicode string

contextFactory = ssl.DefaultOpenSSLContextFactory(key.getvalue(), cert.getvalue())    

给我以下异常。

2018-04-03 16:02:44-0500 [-] OpenSSL.SSL.Error: [('system library', 'fopen', 'File name too long'), ('BIO routines', 'file_ctrl', 'system lib'), ('SSL routines', 'SSL_CTX_use_certificate_file', 'system lib')]

twisted.internet.ssl 正在寻找文件名的字符串或字节对象,io.StringIO 给了我一个 io.StringIO 对象。

有没有办法做到这一点?

使用io.BytesIO代替io.StringIO

from io import BytesIO
key = BytesIO()
key.write(os.environ['SSLKEY'].encode())

Twisted 使用 OpenSSL 来实际实现 TLS。 Twisted 只是围绕 OpenSSL 的 API 提供了一个包装器,使它们更易于使用。

DefaultOpenSSLContextFactory 初始化程序采用证书和密钥文件名,而不是证书和密钥本身。所以,你不能用这个 API.

完成你想要的 然而,

twisted.internet.ssl.CertificateOptions 将接受密钥和证书对象到其初始化程序:

from os import environb
from twisted.internet.ssl import (
    CertificateOptions,
    PrivateCertificate,
)

cert = PrivateCertificate.loadPEM(
    environb['SSLKEY'] + b'\n' + environb['SSLCERT'],
)
key = cert.privateKey

contextFactory = CertificateOptions(
    privateKey=key.original,
    certificate=cert.original,
)

可能还有一种使用 cryptography 库加载证书的更好方法(有望在不久的将来取代大量 twisted.internet.ssl 密钥和证书管理 API)未来)。

另请注意,将您的私钥放入进程中的环境变量中会将其公开给同一主机上的所有其他用户和进程。这是一个非常糟糕的主意(毕竟它不是很私密)。所以你应该把你的钥匙放在别处。