tlsv1_alert_protocol_version tlsv1 skipping simple protocol org error python ssl https cisco

python - simple - ssl tlsv1_alert_protocol_version tlsv1 alert protocol version(_ ssl c 600 skipping



ssl.SSLError: versiĆ³n del protocolo de alerta tlsv1 (7)

A partir de julio de 2018, Pypi ahora requiere que los clientes que se conectan a él usen TLS 1.2. Este es un problema si está utilizando la versión de Python incluida con MacOS (2.7.10) porque solo es compatible con TLS 1.0. Puede cambiar la versión de SSL que Python está utilizando para solucionar el problema o actualizar a una versión más nueva de Python. Use homebrew para instalar la nueva versión de python fuera de la ubicación predeterminada de la biblioteca.

brew install python@2

Estoy usando la API REST para un dispositivo Cisco CMX e intento escribir el código Python que realiza una solicitud GET a la API para obtener información. El código es el siguiente y es el mismo que el del archivo, excepto con la información necesaria modificada.

from http.client import HTTPSConnection from base64 import b64encode # Create HTTPS connection c = HTTPSConnection("0.0.0.0") # encode as Base64 # decode to ascii (python3 stores as byte string, need to pass as ascii value for auth) username_password = b64encode(b"admin:password").decode("ascii") headers = {''Authorization'': ''Basic {0}''.format(username_password)} # connect and ask for resource c.request(''GET'', ''/api/config/v1/aaa/users'', headers=headers) # response res = c.getresponse() data = res.read()

Sin embargo, continuamente recibo el siguiente error:

Traceback (most recent call last): File "/Users/finaris/PycharmProjects/test/test/test.py", line 14, in <module> c.request(''GET'', ''/api/config/v1/aaa/users'', headers=headers) File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1106, in request self._send_request(method, url, body, headers) File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1151, in _send_request self.endheaders(body) File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1102, in endheaders self._send_output(message_body) File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 934, in _send_output self.send(msg) File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 877, in send self.connect() File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1260, in connect server_hostname=server_hostname) File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 377, in wrap_socket _context=self) File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 752, in __init__ self.do_handshake() File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 988, in do_handshake self._sslobj.do_handshake() File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 633, in do_handshake self._sslobj.do_handshake() ssl.SSLError: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:645)

También intenté actualizar OpenSSL pero eso no tuvo ningún efecto.


Creo que TLSV1_ALERT_PROTOCOL_VERSION está alertando de que el servidor no quiere hablarte TLS v1.0. Intente especificar TLS v1.2 solo pegándose en estas líneas:

import ssl context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) # Create HTTPS connection c = HTTPSConnection("0.0.0.0", context=context)

Tenga en cuenta que es posible que necesite versiones suficientemente nuevas de Python (2.7.9+ ¿quizás?) Y posiblemente OpenSSL (tengo "OpenSSL 1.0.2k 26 de enero de 2017" y lo anterior parece funcionar, YMMV)


Lo único que debe hacer es instalar requests[security] en su virtualenv. No debería tener que usar Python 3 (debería funcionar en Python 2.7). Además, si está utilizando una versión reciente de macOS, tampoco tiene que usar homebrew para instalar OpenSSL por separado.

$ virtualenv --python=/usr/bin/python tempenv # uses system python $ . tempenv/bin/activate $ pip install requests $ python >>> import ssl >>> ssl.OPENSSL_VERSION ''OpenSSL 0.9.8zh 14 Jan 2016'' # this is the built-in openssl >>> import requests >>> requests.get(''https://api.github.com/users/octocat/orgs'') requests.exceptions.SSLError: HTTPSConnectionPool(host=''api.github.com'', port=443): Max retries exceeded with url: /users/octocat/orgs (Caused by SSLError(SSLError(1, u''[SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:590)''),)) $ pip install ''requests[security]'' $ python # install requests[security] and try again >>> import requests >>> requests.get(''https://api.github.com/users/octocat/orgs'') <Response [200]>

requests[security] permite que las solicitudes utilicen la última versión de TLS al negociar la conexión. El openssl incorporado en macOS es compatible con TLS v1.2.

Antes de instalar su propia versión de OpenSSL, haga esta pregunta: ¿cómo se carga Google Chrome https://github.com ?


Ninguna de las respuestas aceptadas me señaló en la dirección correcta, y esta sigue siendo la pregunta que surge al buscar el tema, así que aquí está mi saga (parcialmente) exitosa.

Antecedentes: ejecuto un script de Python en un Beaglebone Black que sondea el intercambio de criptomonedas Poloniex usando la biblioteca python-poloniex . De repente dejó de funcionar con el error TLSV1_ALERT_PROTOCOL_VERSION.

Resulta que OpenSSL estaba bien, e intentar forzar una conexión v1.2 fue una gran persecución: la biblioteca usará la última versión según sea necesario. El eslabón débil de la cadena era en realidad Python, que solo definía ssl.PROTOCOL_TLSv1_2 y, por lo tanto, comenzó a admitir TLS v1.2, desde la versión 3.4.

Mientras tanto, la versión de Debian en Beaglebone considera Python 3.3 como la última. La solución alternativa que utilicé fue instalar Python 3.5 desde el origen (3.4 podría haber funcionado también, pero después de horas de prueba y error he terminado):

sudo apt-get install build-essential checkinstall sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev wget https://www.python.org/ftp/python/3.5.4/Python-3.5.4.tgz sudo tar xzf Python-3.5.4.tgz cd Python-3.5.4 ./configure sudo make altinstall

Tal vez no todos esos paquetes sean estrictamente necesarios, pero instalarlos todos a la vez ahorra un montón de reintentos. El altinstall evita que la instalación bloquee los binarios existentes de python, instalando como python3.5 , aunque eso significa que debe reinstalar bibliotecas adicionales. La ./configure tardó unos buenos cinco o diez minutos. El make tomó un par de horas.

Ahora esto todavía no funcionó hasta que finalmente corrí

sudo -H pip3.5 install requests[security]

Que también instala pyOpenSSL , cryptography e idna . Sospecho que pyOpenSSL fue la clave, por lo que tal vez pip3.5 install -U pyopenssl hubiera sido suficiente, pero ya he pasado demasiado tiempo en esto para asegurarme.

En resumen, si obtiene el error TLSV1_ALERT_PROTOCOL_VERSION en Python, probablemente sea porque no puede admitir TLS v1.2. Para agregar soporte, necesita al menos lo siguiente:

  • OpenSSL 1.0.1
  • Python 3.4
  • solicitudes [seguridad]

Esto me ha pasado TLSV1_ALERT_PROTOCOL_VERSION, y ahora puedo luchar con SSL23_GET_SERVER_HELLO en su lugar.

Resulta que esto es volver al problema original de Python seleccionando la versión SSL incorrecta. Esto se puede confirmar utilizando this truco para montar una sesión de solicitudes con ssl_version=ssl.PROTOCOL_TLSv1_2 . Sin él, se usa SSLv23 y aparece el error SSL23_GET_SERVER_HELLO. Con ello, la solicitud tiene éxito.

La batalla final fue forzar la selección de TLSv1_2 cuando la solicitud se realiza en una biblioteca de terceros. Tanto este método como este método deberían haber hecho el truco, pero ninguno hizo ninguna diferencia. Mi solución final es horrible, pero efectiva. Edité /usr/local/lib/python3.5/site-packages/urllib3/util/ssl_.py y cambié

def resolve_ssl_version(candidate): """ like resolve_cert_reqs """ if candidate is None: return PROTOCOL_SSLv23 if isinstance(candidate, str): res = getattr(ssl, candidate, None) if res is None: res = getattr(ssl, ''PROTOCOL_'' + candidate) return res return candidate

a

def resolve_ssl_version(candidate): """ like resolve_cert_reqs """ if candidate is None: return ssl.PROTOCOL_TLSv1_2 if isinstance(candidate, str): res = getattr(ssl, candidate, None) if res is None: res = getattr(ssl, ''PROTOCOL_'' + candidate) return res return candidate

y listo, mi script finalmente puede contactar al servidor nuevamente.


Para Mac OS X

1) Actualice a Python 3.6.5 utilizando el instalador de aplicaciones nativo descargado del sitio web oficial del lenguaje Python https://www.python.org/downloads/

Descubrí que el instalador se encarga de actualizar los enlaces y enlaces simbólicos para el nuevo Python mucho mejor que homebrew.

2) Instale un nuevo certificado usando "./Install Certificates.command" que se encuentra en el directorio actualizado de Python 3.6

> cd "/Applications/Python 3.6/" > sudo "./Install Certificates.command"


Tengo este problema también. En macos, aquí está la solución:

  • Paso 1: preparar reiniciar Python. ahora tienes python3.7 en lugar de la vieja python

  • Paso 2: compila la nueva base env en python3.7. mi ruta es /usr/local/Cellar/python/3.7.2/bin/python3.7

ahora, no te molestará este problema.


Tuve el mismo error y Google me llevó a esta pregunta, así que esto es lo que hice, con la esperanza de que ayude a otros en una situación similar.

Esto es aplicable para OS X.

Comprueba en el Terminal qué versión de OpenSSL tenía:

$ python3 -c "import ssl; print(ssl.OPENSSL_VERSION)" >> OpenSSL 0.9.8zh 14 Jan 2016

Como mi versión de OpenSSL era demasiado antigua, la respuesta aceptada no funcionó.

Entonces tuve que actualizar OpenSSL. Para hacer esto, actualicé Python a la última versión (de la versión 3.5 a la versión 3.6) con Homebrew, siguiendo algunos de los pasos sugeridos here :

$ brew update $ brew install openssl $ brew install python3

Luego estaba teniendo problemas con el PATH y la versión de python que estaba usando, así que creé un nuevo virtualenv asegurándome de que se tomara la versión más nueva de python:

$ virtualenv webapp --python=python3.6

Problema resuelto.