首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何列出静态链接的python版本中可用的所有openssl密码?

如何列出静态链接的python版本中可用的所有openssl密码?
EN

Stack Overflow用户
提问于 2015-02-04 14:09:47
回答 2查看 12.1K关注 0票数 14

在python 2.7.8到2.7.9升级中,ssl模块从

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
_DEFAULT_CIPHERS = 'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2'

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
_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'
)

--我想知道这对实际的“有序SSL密码首选项列表”有什么影响,在Windows.上与我的python建立SSL/TLS连接时使用该列表。

例如,为了弄清楚密码列表扩展到什么“顺序SSL密码首选列表”,我通常使用openssl ciphers命令行(参见手册页),例如,在OpenSSLv1.0.1k中,我可以看到默认python2.7.8密码列表扩展到的内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ 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!

在Linux上,python动态加载与openssl ciphers使用的相同的openssl ciphers库时,这是非常有效的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ 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)

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

我可以很容易地找到OpenSSL的哪个版本用于构建这两个python版本中的每个版本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ 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的库相同的选项编译的,而且从手册页中我们知道

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

那么,是否有一种方法可以获得python模块,以便提供类似于openssl ciphers -v 命令的输出?

EN

回答 2

Stack Overflow用户

发布于 2015-02-10 14:06:24

您可能想看看openssl cipherhttps://github.com/openssl/openssl/blob/master/apps/ciphers.c上的源代码。

关键的步骤似乎是:

  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)); }

SSL_CTX_set_cipher_list函数在Python3.4in_ssl的上下文set_ciphers方法中调用。您可以使用以下方法实现相同的目标:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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(),不幸的是,它没有在Python的_ssl.c中使用。最近可以得到的是SSLSocket实例的SSLSocket方法。(当前)实现是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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。

继续上面的sslsock = SSLSocket(...)示例,在连接套接字之前不能调用sslsock.shared_ciphers()。否则,Python的_ssl模块不会创建一个低级别的OpenSSL SSL对象,这是读取密码所需的。这与ciphers.c中的实现不同,后者在不需要连接的情况下创建一个低级别的SSL对象。

这就是我所取得的成就,我希望这能有所帮助,也许你可以根据这些发现找出你需要什么。

票数 8
EN

Stack Overflow用户

发布于 2015-02-12 03:38:57

简-菲利普·盖尔克的回答要求一个尚未发布的python版本是有用的(请参阅注释),这使得回答关于早期版本的python的问题变得不现实。但这一段启发了我:

在连接套接字之前,...you不能调用sslsock.shared_ciphers()。否则,Python的_ssl模块不会创建一个低级别的OpenSSL SSL对象,这是读取密码所需的。

这让我想到了一个可能的解决方案。都在同一个python程序中:

  • 创建接受任何密码(ciphers='ALL:aNULL:eNULL')的服务器套接字。
  • 使用配置了密码列表的客户端套接字连接到服务器套接字(如果要测试python2.7.8中的默认值,请使用'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2' )。
  • 建立连接后,检查客户端实际选择的密码,并打印它,例如'AES256-GCM-SHA384'。客户端将从其配置的密码列表中选择与服务器提供的密码列表匹配的最高优先级密码。服务器接受任何密码,并使用相同的OpenSSL库在同一个python程序中运行,因此服务器的列表保证是客户端列表的超集。因此,所使用的密码必须是提供给客户端套接字的扩展列表中的最高优先级密码。万岁。
  • 现在重复,再次连接到服务器套接字,但这一次,通过在客户端套接字的密码列表(例如'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:!AES256-GCM-SHA384')中附加对它的否定,排除上一轮选择的密码。
  • 重复,直到SSL握手失败,因为我们的密码用完了。

下面是代码(也可作为github要点):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"""An attempt to produce similar output to "openssl ciphers -v", but for
python's built-in ssl.

To answer https://stackoverflow.com/q/28332448/445073
"""
from __future__ import print_function

import argparse
import logging
import multiprocessing
import os
import socket
import ssl
import sys

def server(log_level, queue):
    logging.basicConfig(level=log_level)
    logger = logging.getLogger("server")

    logger.debug("Creating bind socket")
    bind_sock = socket.socket()
    bind_sock.bind(('127.0.0.1', 0))
    bind_sock.listen(5)

    bind_addr = bind_sock.getsockname()
    logger.debug("Listening on %r", bind_addr)
    queue.put(bind_addr)

    while True:
        logger.debug("Waiting for connection")
        conn_sock, fromaddr = bind_sock.accept()
        conn_sock = ssl.wrap_socket(conn_sock,
                                    ssl_version=ssl.PROTOCOL_SSLv23,
                                    server_side=True,
                                    certfile="server.crt",
                                    keyfile="server.key",
                                    ciphers="ALL:aNULL:eNULL")

        data = conn_sock.read()
        logger.debug("Read %r", data)
        conn_sock.close()
    logger.debug("Done")

def parse_args(argv):
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("--verbose", "-v", action="store_true",
                        help="Turn on debug logging")
    parser.add_argument("--ciphers", "-c",
                        default=ssl._DEFAULT_CIPHERS,
                        help="Cipher list to test. Defaults to this python's "
                        "default client list")
    args = parser.parse_args(argv[1:])
    return args

if __name__ == "__main__":
    args = parse_args(sys.argv)

    log_level = logging.DEBUG if args.verbose else logging.INFO

    logging.basicConfig(level=log_level)
    logger = logging.getLogger("client")

    if not os.path.isfile('server.crt') or not os.path.isfile('server.key'):
        print("Must generate server.crt and server.key before running")
        print("Try:")
        print("openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -nodes -days 365  -subj '/CN=127.0.0.1'")
        sys.exit(1)

    queue = multiprocessing.Queue()
    server_proc = multiprocessing.Process(target=server, args=(log_level, queue))
    server_proc.start()
    logger.debug("Waiting for server address")
    server_addr = queue.get()

    chosen_ciphers = []
    try:
        cipher_list = args.ciphers
        while True:
            client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            client_sock = ssl.wrap_socket(client_sock,
                                          ssl_version=ssl.PROTOCOL_SSLv23,
                                          ciphers=cipher_list)
            logger.debug("Connecting to %r", server_addr)
            client_sock.connect(server_addr)
            logger.debug("Connected")

            chosen_cipher = client_sock.cipher()
            chosen_ciphers.append(chosen_cipher)

            client_sock.write("ping")
            client_sock.close()

            # Exclude the first choice cipher from the list, to see what we get
            # next time.
            cipher_list += ':!' + chosen_cipher[0]
    except ssl.SSLError as err:
        if 'handshake failure' in str(err):
            logger.debug("Handshake failed - no more ciphers to try")
        else:
            logger.exception("Something bad happened")
    except Exception:
        logger.exception("Something bad happened")
    else:
        server_proc.join()
    finally:
        server_proc.terminate()

    print("Python: {}".format(sys.version))
    print("OpenSSL: {}".format(ssl.OPENSSL_VERSION))
    print("Expanding cipher list: {}".format(args.ciphers))
    print("{} ciphers found:".format(len(chosen_ciphers)))
    print("\n".join(repr(cipher) for cipher in chosen_ciphers))

请注意默认情况下如何测试内置到python中的默认密码列表:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
day@laptop ~/test
$ python --version
Python 2.7.8

day@laptop ~/test
$ python ssltest.py -h
usage: ssltest.py [-h] [--verbose] [--ciphers CIPHERS]

optional arguments:
  -h, --help            show this help message and exit
  --verbose, -v         Turn on debug logging (default: False)
  --ciphers CIPHERS, -c CIPHERS
                        Cipher list to test. Defaults to this python's default
                        client list (default:
                        DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2)

因此,我们可以很容易地看到默认的客户端密码列表扩展到什么,以及它是如何从python 2.7.8扩展到2.7.9的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
day@laptop ~/test
$ ~/dists/python-2.7.8-with-pywin32-218-x86/python ssltest.py
Python: 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit (Intel)]
OpenSSL: OpenSSL 1.0.1h 5 Jun 2014
Expanding cipher list: DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2
12 ciphers found:
('AES256-GCM-SHA384', 'TLSv1/SSLv3', 256)
('AES256-SHA256', 'TLSv1/SSLv3', 256)
('AES256-SHA', 'TLSv1/SSLv3', 256)
('CAMELLIA256-SHA', 'TLSv1/SSLv3', 256)
('DES-CBC3-SHA', 'TLSv1/SSLv3', 168)
('AES128-GCM-SHA256', 'TLSv1/SSLv3', 128)
('AES128-SHA256', 'TLSv1/SSLv3', 128)
('AES128-SHA', 'TLSv1/SSLv3', 128)
('SEED-SHA', 'TLSv1/SSLv3', 128)
('CAMELLIA128-SHA', 'TLSv1/SSLv3', 128)
('RC4-SHA', 'TLSv1/SSLv3', 128)
('RC4-MD5', 'TLSv1/SSLv3', 128)

day@laptop ~/test
$ ~/dists/python-2.7.9-with-pywin32-219-x86/python ssltest.py
Python: 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)]
OpenSSL: OpenSSL 1.0.1j 15 Oct 2014
Expanding cipher list: 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
18 ciphers found:
('ECDHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256)
('ECDHE-RSA-AES128-GCM-SHA256', 'TLSv1/SSLv3', 128)
('ECDHE-RSA-AES256-SHA384', 'TLSv1/SSLv3', 256)
('ECDHE-RSA-AES256-SHA', 'TLSv1/SSLv3', 256)
('ECDHE-RSA-AES128-SHA256', 'TLSv1/SSLv3', 128)
('ECDHE-RSA-AES128-SHA', 'TLSv1/SSLv3', 128)
('ECDHE-RSA-DES-CBC3-SHA', 'TLSv1/SSLv3', 112)
('AES256-GCM-SHA384', 'TLSv1/SSLv3', 256)
('AES128-GCM-SHA256', 'TLSv1/SSLv3', 128)
('AES256-SHA256', 'TLSv1/SSLv3', 256)
('AES256-SHA', 'TLSv1/SSLv3', 256)
('AES128-SHA256', 'TLSv1/SSLv3', 128)
('AES128-SHA', 'TLSv1/SSLv3', 128)
('CAMELLIA256-SHA', 'TLSv1/SSLv3', 256)
('CAMELLIA128-SHA', 'TLSv1/SSLv3', 128)
('DES-CBC3-SHA', 'TLSv1/SSLv3', 112)
('ECDHE-RSA-RC4-SHA', 'TLSv1/SSLv3', 128)
('RC4-SHA', 'TLSv1/SSLv3', 128)

我想这回答了我的问题。除非有人能发现这种方法的问题?

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28332448

复制
相关文章
使用VBA基于图标集进行筛选
Excel一直在改进自动筛选功能。可能和许多开发人员一样,当设置了条件,Excel为你进行数据筛选时,Excel会进行循环。当需要在数千行中循环时,此方法就会出现的问题,大大减慢你的过程。相比之下,在VBA中使用自动筛选速度非常快,小列表和大列表之间的时间差可以忽略不计。同时,Excel引入了按图标集筛选的功能,即单元格中显示的条件格式彩色箭头或图表指示器,如下图1所示。
fanjy
2022/11/16
9830
使用VBA基于图标集进行筛选
Python3.4 PIL的使用
from PIL import Image, ImageFilter, ImageDraw, ImageFont, ImageEnhance, ImageFilter image1 = Image.open('C:/Users/hengli/Desktop/1.jpg') image2 = Image.open('C:/Users/hengli/Desktop/2.jpg') def 图片大小(image): w, h = image.size #获得图片的大小(分辨率) r
艳艳代码杂货店
2021/11/02
5530
使用SnpSift filter对VCF文件进行筛选
当完成突变位点注释之后,我们会得到一个巨大的VCF文件,文件大小从几十M到几十G不等。在数量如此多的突变位点中,我们只会根据注释结果从中挑选部分感兴趣的突变位点,这就要求对VCF文件进行过滤。如此大的文件用Excel 操作是不现实的,脚本语言处理大文件时效果也不尽人意,所以SnpEff的开发团队专门开发了一款工具,叫做SnpSift, 用来对VCF文件进行过滤。
生信修炼手册
2020/05/11
3.1K0
MRM中进行变量筛选
1.最近总有人加我好友称呼我的时候把我的姓写错。我的姓是雷厉风行的厉!厉行节约的厉!不明觉厉的厉!不是日历的历啊!
Listenlii-生物信息知识分享
2020/05/29
1.6K0
Python3.4 + pycharm 环境安装 + pycharm使用
以下主要介绍windows环境下的python安装,作为初用python的萌新,建议只在电脑上装一个python版本就好。
可可的测试小栈
2019/10/17
8790
Python使用集合实现素数筛选法
首先生成指定范围内的所有自然数,然后从前往后遍历其中的数字,并分别删除这些数字的倍数,最后剩下的数字都是素数。 很久很久以前,曾经写过一个使用列表+filter()函数的实现,详见Python使用筛选
Python小屋屋主
2018/04/16
2.4K0
Python使用集合实现素数筛选法
如何使用EvtMute对Windows事件日志进行筛选过滤
在这篇文章中,我们将告诉大家如何使用EvtMute来对Windows事件日志进行筛选过滤。EvtMute这款工具允许我们使用YARA来进行攻击性操作,并对已经报告给Windows事件日志的事件进行过滤和筛选。
FB客服
2021/03/09
9020
如何使用EvtMute对Windows事件日志进行筛选过滤
python-进阶教程-对列表中的元素进行筛选
本文主要介绍根据给定条件对列表中的元素进行筛序,剔除异常数据,并介绍列表推导式和生成表达式两种方法。。
kirin
2021/03/11
3.5K0
【利用Python进行金融数据分析】数据的筛选和选取
pd.set_option("display.width",1000) url ="https://raw.githubusercontent.com/jokecamp/FootballData/master/UEFA_European_Championship/Euro%202012/Euro%202012%20stats%20TEAM.csv"
光点神奇
2019/05/28
8420
3.4 使用Axios发送请求
Axios 是一个开源的可以用在浏览器端和 NodeJS 的异步通信框架,她的主要作用就是实现 AJAX 异步通信,其功能特点如下:
Qwe7
2022/07/21
7790
Python3.4 安装 pycrypt
今天做接口测试,有个接口的参数使用了 AES 加密,开发也提供了加密函数的实现,但是 Python2.6 实现的,我习惯使用的是 Python3.4,于是准备做下兼容处理,结果过程中发现安装 pycrypto 库会报错。
py3study
2020/01/10
1K0
python3.4的pygame安装
1.进入官网http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame 下载对应版本的pygame,注意区分32位与64位。
全栈程序员站长
2022/08/25
8090
python3.4的pygame安装
Python 根据AIC准则定义向前逐步回归进行变量筛选(二)
AIC即赤池值,是衡量模型拟合优良性和模型复杂性的一种标准,在建立多元线性回归模型时,变量过多,且有不显著的变量时,可以使用AIC准则结合逐步回归进行变量筛选。AICD数学表达式如下: A I C = 2 p + n ( l o g ( S S E / n ) ) AIC=2p+n(log(SSE/n)) AIC=2p+n(log(SSE/n)) 其中, p p p是进入模型当中的自变量个数, n n n为样本量, S S E SSE SSE是残差平方和,在 n n n固定的情况下, p p p越小, A I C AIC AIC越小, S S E SSE SSE越小, A I C AIC AIC越小,而 p p p越小代表着模型越简洁, S S E SSE SSE越小代表着模型越精准,即拟合度越好,综上所诉, A I C AIC AIC越小,即模型就越简洁和精准。
全栈程序员站长
2022/08/31
2.5K0
Python 根据AIC准则定义向前逐步回归进行变量筛选(二)
Python3.4图片转换素描
from PIL import Image, ImageFilter, ImageOps img = Image.open('C:\Users\hengli\Pictures\lovewallpaper\214926-106.jpg') def dodge(a, b, alpha): return min(int(a255/(256-balpha)), 255) def draw(img, blur=25, alpha=1.0): img1
用户7999227
2021/11/02
6710
使用Python进行并发编程
让计算机程序并发的运行是一个经常被讨论的话题,今天我想讨论一下Python下的各种并发方式。
程序员迪迪
2022/01/13
9600
使用Python进行XML解析
XML 指可扩展标记语言(eXtensible Markup Language),常被设计用来传输和存储数据。 在进行医学图像标注时,我们常使用XML格式文件来存储标注,以下展示了使用Python来提取标注的坐标值。
范中豪
2020/07/14
1.2K0
使用Python进行统计建模
大家好,在之前的文章中我们已经讲解了很多Python数据处理的方法比如读取数据、缺失值处理、数据降维等,也介绍了一些数据可视化的方法如Matplotlib、pyecharts等,那么在掌握了这些基础技能之后,要进行更深入的分析就需要掌握一些常用的建模方法,本文将讲解如何利用Python进行统计分析。和之前的文章类似,本文只讲如何用代码实现,不做理论推导与过多的结果解释(事实上常用的模型可以很轻松的查到完美的推导与解析)。因此读者需要掌握一些基本的统计模型比如回归模型、时间序列等。
刘早起
2020/04/22
1.7K0
使用python进行adsl拨号
import os g_adsl_account = {"name": "adsl", "username": "0512...", "password": "..."} class Adsl(object): #============================================================================== # __init__
py3study
2020/01/09
2.4K0
点击加载更多

相似问题

使用any()函数进行Python筛选数组

22

使用python 3.4安装numpy

12

有状态筛选EXT js 3.4

14

使用Python 3.4旋转视频

11

Python3.4:如何进行xml验证

15
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文