如何列出静态链接的python版本中可用的所有openssl密码? [英] How to list all openssl ciphers available in statically linked python releases?

查看:80
本文介绍了如何列出静态链接的python版本中可用的所有openssl密码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在python 2.7.8到2.7.9升级中,ssl模块已从使用更改为

In the python 2.7.8 to 2.7.9 upgrade, the ssl module changed from using

_DEFAULT_CIPHERS = 'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2'

_DEFAULT_CIPHERS = (
    'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
    'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:ECDH+RC4:'
    'DH+RC4:RSA+RC4:!aNULL:!eNULL:!MD5'
)

我想知道这如何影响在Windows上通过python安装建立SSL/TLS连接时使用的实际有序SSL密码首选项列表".

例如,要弄清楚密码列表扩展到的有序SSL密码首选项列表",我通常使用openssl ciphers命令行(请参阅

For example, to figure out what "ordered SSL cipher preference list" a cipher list expands to, I'd normally use the openssl ciphers command line (see man page) e.g with openssl v1.0.1k I can see what that default python 2.7.8 cipher list expands to:

$ openssl ciphers -v 'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2'
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA384
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA384
ECDHE-RSA-AES256-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1
ECDHE-ECDSA-AES256-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA1
SRP-DSS-AES-256-CBC-SHA SSLv3 Kx=SRP      Au=DSS  Enc=AES(256)  Mac=SHA1
SRP-RSA-AES-256-CBC-SHA SSLv3 Kx=SRP      Au=RSA  Enc=AES(256)  Mac=SHA1
...
snip!

当在python动态加载openssl ciphers使用的相同OpenSSL库的Linux上运行时效果很好.

That works great when on Linux where python is dynamically loading the same OpenSSL library that openssl ciphers uses:

$ ldd /usr/lib/python2.7/lib-dynload/_ssl.x86_64-linux-gnu.so | grep libssl
        libssl.so.1.0.0 => /lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007ff75d6bf000)
$ ldd /usr/bin/openssl | grep libssl
        libssl.so.1.0.0 => /lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007fa48f0fe000)

但是,在Windows上,Python版本似乎可以静态链接OpenSSL库.这意味着openssl ciphers命令无法帮助我,因为它使用了不同版本的库,该库可能支持与python内置库不同的密码.

However, on Windows the Python build appears to statically link the OpenSSL library. This means that the openssl ciphers command cannot help me, because it uses a different version of the library, which may have support for different ciphers than the library built into python.

我可以很容易地找出使用哪个版本的OpenSSL轻松构建两个python版本:

I can find out what version of OpenSSL was used to build each of the two python releases easily enough:

$ python-2.7.8/python -c 'import ssl; print ssl.OPENSSL_VERSION'
OpenSSL 1.0.1h 5 Jun 2014

$ python-2.7.9/python -c 'import ssl; print ssl.OPENSSL_VERSION'
OpenSSL 1.0.1j 15 Oct 2014

但是,即使我可以找到并下载用于1.0.1h和1.0.1j发行版的openssl命令行版本,也无法确定它们使用与内置于python中的lib相同的选项进行编译,并且从手册页中我们知道

But even if I could find and download a build of the openssl command line for both the 1.0.1h and 1.0.1j releases, I cannot be sure that they were compiled with the same options as the lib built into python, and from the man page we know that

某些OpenSSL的编译版本可能未包含此处列出的所有密码,因为某些密码在编译时已被排除.

Some compiled versions of OpenSSL may not include all the ciphers listed here because some ciphers were excluded at compile time.

那么,有没有办法让python的ssl模块为我提供类似于openssl ciphers -v命令的输出?

So, is there a way to get python's ssl module to give me output similar to that from the openssl ciphers -v command?

推荐答案

您可能想在关键步骤似乎是:

  1. meth = SSLv23_server_method();
  2. ctx = SSL_CTX_new(meth);
  3. SSL_CTX_set_cipher_list(ctx, ciphers),而ciphers是您的字符串
  4. ssl = SSL_new(ctx);
  5. sk = SSL_get1_supported_ciphers(ssl);
  6. for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { print SSL_CIPHER_get_name(sk_SSL_CIPHER_value(sk, i)); }
  1. meth = SSLv23_server_method();
  2. ctx = SSL_CTX_new(meth);
  3. SSL_CTX_set_cipher_list(ctx, ciphers), whereas ciphers is your string
  4. ssl = SSL_new(ctx);
  5. sk = SSL_get1_supported_ciphers(ssl);
  6. for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { print SSL_CIPHER_get_name(sk_SSL_CIPHER_value(sk, i)); }

在Python 3.4中,_ssl的set_ciphers方法中为上下文调用了SSL_CTX_set_cipher_list函数.您可以使用以下方法实现相同的目的:

The SSL_CTX_set_cipher_list function is called in Python 3.4 in _ssl's set_ciphers method for contexts. You can achieve the same using:

import socket
from ssl import SSLSocket
sslsock = SSLSocket(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
sslsock.context.set_ciphers('DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2')

下一步将调用SSL_get1_supported_ciphers(),不幸的是,该SSL_get1_supported_ciphers()在Python的 _ssl.c .您可以获得的最接近的是SSLSocket实例的shared_ciphers()方法. (当前的)实现是

The next step would be calling SSL_get1_supported_ciphers() which, unfortunately, is not used in Python's _ssl.c. The closest you can get is the shared_ciphers() method of SSLSocket instances. The (current) implementation is

static PyObject *PySSL_shared_ciphers(PySSLSocket *self)
{
    [...]
    ciphers = sess->ciphers;
    res = PyList_New(sk_SSL_CIPHER_num(ciphers));
    for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
        PyObject *tup = cipher_to_tuple(sk_SSL_CIPHER_value(ciphers, i));
        [...]
        PyList_SET_ITEM(res, i, tup);
    }
    return res;
}

也就是说,此循环与上述ciphers.c实现中的循环非常相似,并以与ciphers.c中的循环相同的顺序返回Python密码列表.

That is, this loop is very similar as in the ciphers.c implementation above, and returns a Python list of ciphers, in the same order as the loop in ciphers.c would.

继续上面的sslsock = SSLSocket(...)示例,您不能在连接套接字之前调用sslsock.shared_ciphers().否则,Python的_ssl模块不会创建读取密码所需的低级OpenSSL SSL对象.这与ciphers.c中的实现不同,该实现无需连接即可创建低级SSL对象.

Continuing with the sslsock = SSLSocket(...) example from above, you cannot call sslsock.shared_ciphers() before the socket is connected. Otherwise, Python's _ssl module does not create a low-level OpenSSL SSL object, which is needed to read the ciphers. That is different from the implementation in ciphers.c, which creates a low level SSL object without requiring a connection.

那是我走了多远,希望对您有所帮助,也许您可​​以根据这些发现来弄清楚您的需求.

That is how far I got, I hope that helps, and maybe you can figure out what you need based on these findings.

这篇关于如何列出静态链接的python版本中可用的所有openssl密码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆