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

时间:2018-04-03 21:06:38

标签: python python-3.x twisted stringio twisted.internet

我想从环境变量中提取我的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对象。

无论如何要做到这一点?

2 个答案:

答案 0 :(得分:1)

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。

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

答案 1 :(得分:0)

使用io.BytesIO代替io.StringIO

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