簡體   English   中英

python ssl ssl.SSLError: [SSL: UNSUPPORTED_PROTOCOL] 不支持的協議 (_ssl.c:590)

[英]python ssl ssl.SSLError: [SSL: UNSUPPORTED_PROTOCOL] unsupported protocol (_ssl.c:590)

使用 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)

如果您在基於 debian 的操作系統或 docker 鏡像中運行您的請求,您需要更改您的 SSL 配置。 Debian 目前默認使用 SSL v1.2 +。

如果需要,您可以手動編輯 openssl.cnf,但有一個更快的解決方案:

sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1.0/' /etc/ssl/openssl.cnf

它對我的情況有所幫助,對帶有舊 SSL 的 URL 的請求現在返回了 200 響應。

顯然 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 

可能您的服務器暴露了舊的、不安全的 TLS 協議版本,現代 OpenSSL 配置為不允許。

https://stackoverflow.com/a/53065682/6214034可能會有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM