2017-06-01 10 views
5

मैं एक सिस्को CMX उपकरण के लिए API का उपयोग कर रहाssl.SSLError: tlsv1 चेतावनी प्रोटोकॉल संस्करण

(देखें: https://www.cisco.com/c/en/us/td/docs/wireless/mse/10-2/api/b_cg_CMX_REST_API_Getting_Started_Guide/b_cg_CMX_REST_API_Getting_Started_Guide_chapter_01.html)

और अजगर कोड है जिसके लिए एपीआई के GET अनुरोध करता है लिखने की कोशिश कर जानकारी। कोड निम्नानुसार है और आवश्यक जानकारी को छोड़कर फ़ाइल में वही है।

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() 

हालांकि, मैं लगातार निम्न त्रुटि हो रही है:

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) 

मैं भी OpenSSL को अद्यतन करने की कोशिश की, लेकिन वह कोई प्रभाव नहीं पड़ा।

+1

https://github.com/CiscoDevNet/devnet-express-dna-issues/issues/16 देखें। ऐसा लगता है कि आप अपने पायथन में ओपनएसएसएल के पुराने संस्करण का उपयोग कर रहे हैं। यह आम तौर पर मामला है यदि आप मैक पर हैं जो ओपनएसएसएल के वास्तव में पुराने और पुराने संस्करण के साथ भेज दिया गया है। –

+0

मैं इस समस्या को विंडोज़ पर विमोस माइक्रोकंट्रोलर के लिए बाइनरी उपकरण प्राप्त करने पर चलाता हूं। कारण यह था कि Google ने मुझे अजगर 2.7.3 (पुराना) संस्करण डाउनलोड पेज लिया था, मैंने सोचा था कि यह नवीनतम था ... वर्तमान में 2.7.14 नवीनतम है और इसमें अब यह समस्या नहीं है, यह "स्वचालित रूप से" । – Feri

उत्तर

7

मुझे एक ही त्रुटि थी और Google ने मुझे इस प्रश्न पर लाया, इसलिए मैंने यह किया कि यह है कि यह दूसरों को इसी तरह की स्थिति में मदद करता है।

यह ओएस एक्स

टर्मिनल में चेक OpenSSL का कौन सा संस्करण मैं था के लिए लागू होता है:

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

से OpenSSL के अपने संस्करण बहुत पुराना था, स्वीकार किए जाते हैं जवाब काम नहीं किया।

तो मुझे ओपनएसएसएल अपडेट करना पड़ा। ऐसा करने के लिए, मैं नवीनतम संस्करण Homebrew के साथ (संस्करण 3.5 से संस्करण 3.6 के लिए) के लिए अजगर अद्यतन, चरणों में से कुछ निम्नलिखित सुझाव दिया here:

$ brew update 
$ brew install openssl 
$ brew install python3 

तब मैं और पथ के साथ समस्याओं अजगर के संस्करण हो रही थी

$ virtualenv webapp --python=python3.6 

समस्या हल हो जाती: इस्तेमाल किया जा रहा है, तो मैं बस एक नया virtualenv सुनिश्चित करें कि अजगर के नवीनतम संस्करण में लिया गया था करते समय बनाए गए। स्वीकार किए जाते हैं जवाब में से

+1

स्वीकृत उत्तर ने इसे पूरी तरह से कवर नहीं किया है, लेकिन टिप्पणियों में मैंने अप्रत्यक्ष रूप से ओपनएसएसएल को अपडेट करने की आवश्यकता का उल्लेख किया है। क्षमा करें कि यह अधिक स्पष्ट नहीं था, और इसे जोड़ने के लिए धन्यवाद! – finaris

+0

वर्चुअलनेव समस्या हल करता है :) – karakays

+0

अगर किसी को अभी भी समस्याएं आ रही हैं तो इसने वास्तव में मेरी मदद की: https://stackoverflow.com/a/46308535/1526702 –

2

मेरा मानना ​​है कि TLSV1_ALERT_PROTOCOL_VERSION जो आपको सचेत कर रहा है कि सर्वर आप के लिए टीएलएस v1.0 बात करने के लिए नहीं चाहता है। केवल इन पंक्तियों में चिपके द्वारा टीएलएस v1.2 निर्दिष्ट करने के लिए प्रयास करें: (? शायद 2.7.9+)

import ssl 
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) 

# Create HTTPS connection 
c = HTTPSConnection("0.0.0.0", context=context) 

ध्यान दें, आप अजगर के लिए पर्याप्त रूप से नए संस्करण की आवश्यकता हो सकती है और संभवतः OpenSSL (मेरे पास है "OpenSSL 1.0.2k 26 जनवरी 2017 "और उपर्युक्त काम करने लगता है, वाईएमएमवी)

+1

आपके पास ओपनएसएसएल 0.9.8 और टीएलएस 1.2 काम करता है? मुझे यह बहुत संदेह है: टीएलएस 1.2 केवल ओपनएसएसएल 1.0.1 के बाद से समर्थित है। –

+0

टीएलएस 1.2 ओपनएसएसएल 0.9.8 के साथ काम नहीं किया, लेकिन मैंने दुभाषिया को एक में बदल दिया जिसमें ओपनएसएसएल 1.0.2k और टीएलएस 1.2 काम किया था (और इस प्रकार एपीआई को कॉल सफल हुआ)। – finaris

+1

@SteffenUllrich आह हाँ, 'python -c 'आयात ssl कर रहा है; प्रिंट (एसएसएल।OPENSSL_VERSION) '' पुष्टि करता है कि मेरा (होमब्री स्थापित) पायथन "ओपनएसएसएल 1.0.2k 26 जनवरी 2017" से जुड़ा हुआ है। मैंने दिखाया गया 0.9.8zh संस्करण स्ट्रिंग 'openssl संस्करण' चलाने से था, जो मेरी पुरानी प्रणाली-व्यापी स्थापना होनी चाहिए। –

3

कोई भी मुझे सही दिशा में इशारा किया, और यह अभी भी सवाल है कि ऊपर आता है जब विषय खोज, इसलिए यहाँ मेरी (आंशिक रूप से) सफल गाथा है।

पृष्ठभूमि: मैं एक बीगलबोन ब्लैक पर एक पायथन लिपि चलाता हूं जो python-poloniex लाइब्रेरी का उपयोग करके क्रिप्टोकुरेंसी एक्सचेंज पोलोनिक्स का चुनाव करता है। यह अचानक TLSV1_ALERT_PROTOCOL_VERSION त्रुटि के साथ काम करना बंद कर दिया।

बाहर कर देता है कि OpenSSL ठीक था, और एक v1.2 कनेक्शन के लिए मजबूर करने की कोशिश कर रहा एक विशाल जंगली हंस का पीछा था - पुस्तकालय नवीनतम संस्करण के रूप में आवश्यक का उपयोग करेगा। श्रृंखला में कमजोर लिंक वास्तव में पायथन था, जिसे केवल ssl.PROTOCOL_TLSv1_2 परिभाषित किया गया था, और इसलिए संस्करण 3.4 के बाद से टीएलएस v1.2 का समर्थन करना शुरू किया।

इस बीच, Beaglebone पर डेबियन के संस्करण अजगर 3.3 नवीनतम समझता है।वैकल्पिक हल मैं इस्तेमाल किया स्रोत से अजगर 3.5 स्थापित करने के लिए था (3.4 अंत में भी काम किया हो सकता है, लेकिन परीक्षण और त्रुटि के घंटे के बाद मैं यहां हटाया गया हूँ): हो सकता है

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 

नहीं उन सभी संकुल अत्यंत आवश्यक होता है, लेकिन स्थापित करने वे सब एक बार में retries का एक गुच्छा बचाता है। altinstall मौजूदा पायथन बाइनरी clobbering से स्थापित करने से रोकता है, इसके बजाय python3.5 के रूप में स्थापित, हालांकि इसका मतलब है कि आपको अतिरिक्त पुस्तकालयों को फिर से स्थापित करना होगा। ./configure ने अच्छा पांच या दस मिनट लिया। make में कुछ घंटे लगे।

अब यह अभी भी जब तक मैं अंत में

sudo -H pip3.5 install requests[security] 

कौन सा भी स्थापित करता है pyOpenSSL, cryptography और idna भाग गया काम नहीं किया। मुझे संदेह है कि pyOpenSSL कुंजी थी, इसलिए शायद pip3.5 install -U pyopenssl पर्याप्त होगा लेकिन मैंने इसे सुनिश्चित करने के लिए पहले से ही बहुत लंबा खर्च किया है।

तो संक्षेप में, यदि आपको पायथन में TLSV1_ALERT_PROTOCOL_VERSION त्रुटि मिलती है, तो संभवतः क्योंकि आप टीएलएस v1.2 का समर्थन नहीं कर सकते हैं। समर्थन जोड़ने के लिए, आप की जरूरत कम से कम निम्नलिखित:

  • OpenSSL 1.0.1
  • अजगर 3.4
  • के अनुरोध [सुरक्षा]

यह मैं अतीत TLSV1_ALERT_PROTOCOL_VERSION मिल गया है, और अब मैं मिल इसके बजाय SSL23_GET_SERVER_HELLO के साथ लड़ाई करने के लिए।

यह गलत है कि यह गलत एसएसएल संस्करण का चयन करने वाले पायथन के मूल अंक पर वापस आ गया है। के साथ अनुरोध सत्र को माउंट करने के लिए this चाल का उपयोग करके इसकी पुष्टि की जा सकती है। इसके बिना, SSLv23 का उपयोग किया जाता है और SSL23_GET_SERVER_HELLO त्रुटि प्रकट होती है। इसके साथ, अनुरोध सफल होता है।

अंतिम लड़ाई किसी तीसरे पक्ष की लाइब्रेरी में अनुरोध गहराई जाने पर टीएलएसवी 1_2 को उठाया जाना था। this method और this method दोनों को चाल चलनी चाहिए, लेकिन न तो कोई फर्क पड़ता। मेरा अंतिम समाधान भयानक है, लेकिन प्रभावी है। मैं /usr/local/lib/python3.5/site-packages/urllib3/util/ssl_.py संपादित और

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 

बदल

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 

और देखा, मेरी स्क्रिप्ट अंत में फिर से सर्वर से संपर्क कर सकते हैं।

+0

धन्यवाद @ हेथ! मैं पुष्टि करता हूं कि मुझे पाइथन 2.7 चलाने और पोलोनिक्स एपीआई से कनेक्ट करने की कोशिश करने में एक ही समस्या थी, और केवल 'पीआईपी इंस्टॉल अनुरोध [सुरक्षा]' को चलाने से समस्या हल हो गई। Python3 में अपग्रेड करने की कोई ज़रूरत नहीं है :) बहुत सराहना की! –

संबंधित मुद्दे