使用python 2.7.10或2.7.9时出现此错误但与python 2.7.6一起使用(未测试其他版本)
OpenSLL版本:
openssl version -a
OpenSSL 1.0.1f 6 Jan 2014
built on: Thu Jun 11 15:30:15 UTC 2015
platform: debian-amd64
options: bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx)
compiler: cc -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
OPENSSLDIR: "/usr/lib/ssl"
的Python:
import ssl
print ssl.OPENSSL_VERSION_NUMBER
268439663L
print get_server_certificate(('someInternalIp', 443), ssl_version=ssl.PROTOCOL_SSLv23)
堆栈跟踪:
File "C:\Python27\lib\ssl.py", line 985, in get_server_certificate
with closing(context.wrap_socket(sock)) as sslsock:
File "C:\Python27\lib\ssl.py", line 352, in wrap_socket
_context=self)
File "C:\Python27\lib\ssl.py", line 579, in __init__
self.do_handshake()
File "C:\Python27\lib\ssl.py", line 808, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: UNSUPPORTED_PROTOCOL] unsupported protocol (_ssl.c:590)
答案 0 :(得分:3)
显然python 2.7.6使用了这个密码套件:
DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2
现在它使用:
# Disable weak or insecure ciphers by default
# (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL')
# Enable a better set of ciphers by default
# This list has been explicitly chosen to:
# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
# * Prefer ECDHE over DHE for better performance
# * Prefer any AES-GCM over any AES-CBC for better performance and security
# * Then Use HIGH cipher suites as a fallback
# * Then Use 3DES as fallback which is secure but slow
# * Disable NULL authentication, NULL encryption, and MD5 MACs for security
# reasons
_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:!aNULL:'
'!eNULL:!MD5'
)
我必须构建以下代码,以便在使用旧密码套件时通知我。我可以这样做是因为我对检索证书感兴趣
from socket import socket
from ssl import SSLContext
from ssl import PROTOCOL_SSLv23
from ssl import DER_cert_to_PEM_cert
WEAK_CTX = SSLContext(PROTOCOL_SSLv23)
WEAK_CTX.set_ciphers('ALL:!aNULL:!eNULL')
NORMAL_CTX = SSLContext(PROTOCOL_SSLv23)
NORMAL_CTX.set_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:!aNULL:'
'!eNULL:!MD5'
)
def getCertificate(addr):
sock = socket()
sock.connect(addr)
isWeakCipher = False
try:
sslobj = NORMAL_CTX._wrap_socket(sock._sock, server_side=False)
sslobj.do_handshake()
except Exception as ex:
if hasattr(ex, 'reason') and ex.reason == 'SSLV3_ALERT_HANDSHAKE_FAILURE':
sock.close()
sock = socket()
sock.connect(addr)
sslobj = WEAK_CTX._wrap_socket(sock._sock, server_side=False)
sslobj.do_handshake()
isWeakCipher = True
else:
raise
cipher = sslobj.cipher()
cert = sslobj.peer_certificate(True)
sock.close()
return isWeakCipher, cipher, cert
答案 1 :(得分:2)
如果您在基于debian的OS或docker映像中运行请求,则需要更改SSL配置。默认情况下,Debian目前可用于SSL v1.2 +。
您可以根据需要手动编辑openssl.cnf,但是有一个更快的解决方案:
sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1.0/' /etc/ssl/openssl.cnf
对于我来说,这很有帮助,对使用旧SSL的URL的请求现在可以返回200响应。
答案 2 :(得分:0)
您的服务器可能正在暴露TLS协议的旧的,不安全的版本,而现代OpenSSL配置为不允许该协议。