Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python使用TLSv1.2和前向保密性粘贴SSL服务器_Python_Macos_Ssl_Openssl - Fatal编程技术网

Python使用TLSv1.2和前向保密性粘贴SSL服务器

Python使用TLSv1.2和前向保密性粘贴SSL服务器,python,macos,ssl,openssl,Python,Macos,Ssl,Openssl,对于Mac OS X上的Python应用程序,我需要设置一个带有TLSv1.2的HTTPS服务器,具有前向保密性,并且没有RC4密码。使用Paste和pyOpenSSL,我编写了以下代码: from paste import httpserver from OpenSSL import SSL context = SSL.Context(SSL.SSLv23_METHOD) context.use_privatekey_file("/Path/to/my/private.key") conte

对于Mac OS X上的Python应用程序,我需要设置一个带有TLSv1.2的HTTPS服务器,具有前向保密性,并且没有RC4密码。使用Paste和pyOpenSSL,我编写了以下代码:

from paste import httpserver
from OpenSSL import SSL

context = SSL.Context(SSL.SSLv23_METHOD)
context.use_privatekey_file("/Path/to/my/private.key")
context.use_certificate_chain_file("/Path/to/my/chain-cert.pem")
context.set_options(SSL.OP_NO_SSLv2)
context.set_options(SSL.OP_NO_SSLv3)
context.set_options(SSL.OP_SINGLE_DH_USE)
context.set_cipher_list("EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4")
logger.debug("OPENSSL version: %s" % SSL.SSLeay_version(SSL.SSLEAY_VERSION))

httpserver.serve(app_logged, host=http_host, port=http_port, server_version=server_version, ssl_context=context, use_threadpool=True, threadpool_workers=15, request_queue_size=5)
但Safari、Chrome和OpenSSL客户端未能连接到我的服务器,错误为“无共享密码”。那么,我做错了什么

注意:Python(2.7.6)和OpenSSL(0.9.8)的默认OS X版本与TLSv1.2不兼容,因此我必须从源代码编译OpenSSL 1.0.2和Python 2.7.10

如果我检查我的OpenSSL密码列表,它会告诉我:

$ /usr/local/bin/openssl ciphers -V 'EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4'
0xC0,0x2C - ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD
0xC0,0x2B - ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128) Mac=AEAD
0xC0,0x30 - ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
0xC0,0x2F - ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(128) Mac=AEAD
0xC0,0x24 - ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA384
0xC0,0x23 - ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA256
0xC0,0x28 - ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA384
0xC0,0x27 - ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA256
0xC0,0x14 - ECDHE-RSA-AES256-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1
0xC0,0x0A - ECDHE-ECDSA-AES256-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA1
0xC0,0x13 - ECDHE-RSA-AES128-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA1
0xC0,0x09 - ECDHE-ECDSA-AES128-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA1
0x00,0x9F - DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH       Au=RSA  Enc=AESGCM(256) Mac=AEAD
0x00,0x6B - DHE-RSA-AES256-SHA256   TLSv1.2 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA256
0x00,0x39 - DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1
0x00,0x88 - DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH       Au=RSA  Enc=Camellia(256) Mac=SHA1
0x00,0x9E - DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH       Au=RSA  Enc=AESGCM(128) Mac=AEAD
0x00,0x67 - DHE-RSA-AES128-SHA256   TLSv1.2 Kx=DH       Au=RSA  Enc=AES(128)  Mac=SHA256
0x00,0x33 - DHE-RSA-AES128-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(128)  Mac=SHA1
0x00,0x9A - DHE-RSA-SEED-SHA        SSLv3 Kx=DH       Au=RSA  Enc=SEED(128) Mac=SHA1
0x00,0x45 - DHE-RSA-CAMELLIA128-SHA SSLv3 Kx=DH       Au=RSA  Enc=Camellia(128) Mac=SHA1
例如,我知道Safari 8与密码“ECDHE-RSA-AES128-SHA256”兼容,所以为什么会出现“无共享密码”错误

$ /usr/local/bin/openssl s_client -connect 192.168.0.17:4443 -tls1_2
CONNECTED(00000003)
140735274361680:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:1472:SSL alert number 40
140735274361680:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:656:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol  : TLSv1.2
Cipher    : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg   : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1439975452
Timeout   : 7200 (sec)
Verify return code: 0 (ok)
---
备选方案:如果我将密码列表更改为

context.set_cipher_list("HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:@STRENGTH")
它可以工作,浏览器和openssl客户端能够使用协议TLSv1.2上的密码“AES256-GCM-SHA384”建立安全连接,但它不是ECDHE密码(因此没有前向保密性)

编辑正确答案:

对于DH密码,您需要一个PEM格式的DH参数文件,您可以使用以下命令生成一个文件:

$ /usr/local/bin/openssl dhparam 2048 -out dhparams.pem
对于ECDHE密码,需要为SSL上下文设置椭圆曲线。您可以使用pyOpenSSL在系统上检索可用曲线:

OpenSSL.crypto.get_elliptic_curves()
这为我们提供了正确的python代码:

from paste import httpserver
from OpenSSL import SSL
from OpenSSL import crypto

context = SSL.Context(SSL.SSLv23_METHOD)
context.use_privatekey_file("/Path/to/my/private.key")
context.use_certificate_chain_file("/Path/to/my/chain-cert.pem")
context.load_tmp_dh("/Path/to/my/dhparams.pem")
context.set_tmp_ecdh(crypto.get_elliptic_curve("prime256v1"))
context.set_options(SSL.OP_NO_SSLv2)
context.set_options(SSL.OP_NO_SSLv3)
context.set_options(SSL.OP_SINGLE_DH_USE)
context.set_cipher_list("EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4")
logger.debug("OPENSSL version: %s" % SSL.SSLeay_version(SSL.SSLEAY_VERSION))

httpserver.serve(app_logged, host=http_host, port=http_port, server_version=server_version, ssl_context=context, use_threadpool=True, threadpool_workers=15, request_queue_size=5)

要支持DH密码(DHE-RSA-…),您需要有一个DH params文件并指定它:

 context.load_tmp_dh("dhparams.pem")
要创建这样的文件,可以使用OpenSSL

 openssl dhparam -out dhparams.pem 2048
为了支持ECDH密码,您需要指定应该使用哪条曲线。我没有一个支持它的pyOpenSSL版本,但根据协议,它应该是

context.set_tmp_ecdh( OpenSSL.crypto.get_elliptic_curve( "prime256v1" ))

我将把它留在这里,因为它也适用于内置库

import ssl
from socket import *

context = ssl.create_default_context()
context.set_ciphers('ECDHE+AESGCM:!ECDSA')
context.load_dh_params("dhparams.pem")
context.set_ecdh_curve("prime256v1")

sock = socket()
sock.connect(('hostname', 443))
sock = context.wrap_socket(sock, server_side=False, server_hostname='hostname')
由于上述答案和问题是关于,我知道这可能不是100%在正确的球场


但是在搜索了一下为什么我会得到ssl.SSLError:[ssl:SSLV3\u ALERT\u HANDSHAKE\u FAILURE]SSLV3 ALERT HANDSHAKE FAILURE(\u ssl.c:1045)之后,没有任何关于为什么会发生这种情况的详细信息,这篇文章救了我一天。。但我也认为可以通过
ssl
(我确信,这可能使用OpenSSL,但仍然认为这在这里可能很有用)。

您可以尝试使用
OpenSSL s_server-cipher…
而不是paste/python来确定它是否与OpenSSL安装或paste/python有关吗?好主意@SteffenUllrich,
$/usr/local/bin/openssl s_服务器-密码'EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!阿努尔:!埃努尔:!低:!3DES:!MD5:!经验:!PSK:!SRP:!决策支持系统:!RC4'-accept 4443-cert/Path/to/my/chain-cert.pem-key/Path/to/my/private.key-no_ssl2-no_ssl3-www
似乎有效<代码>$/usr/local/bin/openssl s_客户端-连接192.168.0.17:4443-tls1_2使用TLSv1.2协议和ECDHE-RSA-AES256-GCM-SHA384密码建立连接。似乎是python/paste或pyOpenSSL的问题?我成功地使用了最终版本,并从ssl实验室获得了a评级。但我必须升级pyOpenSSL。看:太好了!它可以工作,只是有一点输入错误。
get_椭圆曲线('prime256v1')
get_椭圆曲线()
方法用于列出当前版本的OpenSSL支持的曲线。我现在拥有Safari使用的密码ECDHE_RSA_和_AES_256_CBC_SHA384,并且在ssllabs.com SSL服务器测试中获得“a”评级。多谢各位@布文吉:评论不是针对新问题的。如果你想得到答案,请提出一个新问题,并添加必要的细节以重现问题。@BuvinJ:只需提出一个新问题,不要忘记添加重现问题所需的所有信息。