如何使用存储在python中的字符串变量中的证书打开ssl套接字

kaa*_*ala 24 python sockets ssl certificate

在Python中,ssl.wrap_socket可以从文件中读取证书,ssl.wrap_socket要求将证书作为文件路径.

如何使用从字符串变量读取的证书启动SSL连接?

我的主机环境不允许写入文件,而tempfile模块不起作用
我正在使用Python 2.7.
我将证书存储在MySQL中并作为字符串读取.

编辑:我放弃了,这基本上是需要用纯Python代码实现ssl,这超出了我目前的知识.

cne*_*son 26

查看源代码,ssl.wrap_socket直接调用本机代码(openssl)函数SSL_CTX_use_cert_chain_file,该函数需要一个文件路径,因此您无法尝试执行此操作.

以供参考:

在ssl/init .py中我们看到:

def wrap_socket(sock, keyfile=None, certfile=None,
                server_side=False, cert_reqs=CERT_NONE,
                ssl_version=PROTOCOL_SSLv23, ca_certs=None,
                do_handshake_on_connect=True):

    return SSLSocket(sock, keyfile=keyfile, certfile=certfile,
                   server_side=server_side, cert_reqs=cert_reqs,
                   ssl_version=ssl_version, ca_certs=ca_certs,
                   do_handshake_on_connect=do_handshake_on_connect)
Run Code Online (Sandbox Code Playgroud)

将我们指向SSLSocket构造函数(位于同一文件中),我们看到以下情况:

self._sslobj = _ssl2.sslwrap(self._sock, server_side,
                                     keyfile, certfile,
                                     cert_reqs, ssl_version, ca_certs)
Run Code Online (Sandbox Code Playgroud)

_ssl2在C(_ssl2.c)中实现

看一下sslwrap函数,我们看到它正在创建一个新对象:

    return (PyObject *) newPySSLObject(Sock, key_file, cert_file,
                                       server_side, verification_mode,
                                       protocol, cacerts_file);
Run Code Online (Sandbox Code Playgroud)

看一下该对象的构造函数,我们最终看到:

            ret = SSL_CTX_use_certificate_chain_file(self->ctx,
                                                     cert_file);
Run Code Online (Sandbox Code Playgroud)

该函数在openssl中定义,所以现在我们需要切换到该代码库.

在ssl/ssl_rsa.c中,我们最终在函数中找到:

BIO_read_filename(in,file) 
Run Code Online (Sandbox Code Playgroud)

如果你深入挖掘BIO代码(openssl的一部分),你最终会得到一个正常的fopen():

fp=fopen(ptr,p);
Run Code Online (Sandbox Code Playgroud)

所以它看起来像现在写的.它必须位于C的fopen()可打开的文件中.

此外,由于python的ssl库如此快速地跳转到C,我也没有在一个变通方法中看到monkeypatch的一个明显的位置.


jud*_*ira 8

从 Python 3.4 开始,您可以使用 SSLContext#load_verify_locations:

context = ssl.SSLContext()
context.load_verify_locations(cadata=cert)  # Where cert is str.
Run Code Online (Sandbox Code Playgroud)

来自https://docs.python.org/3/library/ssl.html#ssl.SSLContext.load_verify_locations


Dim*_*nek 5

尽管ssl模块源确认了API不支持您想要的内容,但请快速查看:http: //code.google.com/codesearch#2T6lfGELm_A/trunk/Modules/_ssl.c&q=sslwrap&type=cs

这并不是说不可能,你可以创建一个命名管道,从Python提供一端并将文件名提供给ssl模块.

为了更简单,安全性更低,请将内存转储到mkstemp()文件.

你甚至可以挂载FUSE卷和拦截文件回调.

最后,在运行时使用ctypes来破解ssl上下文,并在C配方之后从缓冲区加载cert/ket从内存中读取证书文件而不是使用OpenSSL的文件之前已经完成了这些事情,但这不是最微弱的事情.

看起来你正试图摆脱例如app引擎"jail",也许这是不可能的?

如果您对ssl实现不挑剔,可以使用M2Crypto,TLS Lite,pyOpenSSL或其他.早期的是纯python,你绝对可以破解它使用内存证书/密钥.