2015-01-06 8 views
14

पायथन 2.7.9 अब SSL प्रमाण पत्र सत्यापन के बारे में अधिक सख्त है। बहुत बढ़िया!पायथन Urllib2 एसएसएल त्रुटि

मुझे आश्चर्य नहीं है कि पहले जो काम कर रहे थे वे अब CERTIFICATE_VERIFY_FAILED त्रुटियां प्राप्त कर रहे हैं। लेकिन मुझे लगता है कि वे काम नहीं कर रहे हैं (प्रमाण पत्र सत्यापन पूरी तरह से अक्षम किए बिना)।

एक प्रोग्राम https पर अमेज़ॅन S3 से कनेक्ट करने के लिए urllib2 का उपयोग कर रहा था।

मैं "verisign.pem" नामक एक फाइल में जड़ CA प्रमाणपत्र डाउनलोड करने और इस प्रयास करें:

import urllib2, ssl 
context = ssl.create_default_context() 
context.load_verify_locations(cafile = "./verisign.pem") 
print context.get_ca_certs() 
urllib2.urlopen("https://bucket.s3.amazonaws.com/", context=context) 

और मैं अभी भी CERTIFICATE_VERIFY_FAILED हो त्रुटियों, भले ही जड़ सीए लाइन 4 में सही ढंग से छपा है।

openssl इस सर्वर से जुड़ा कनेक्ट कर सकते हैं।

openssl s_client -showcerts -connect bucket.s3.amazonaws.com:443 < /dev/null 

मैं श्रृंखला में पिछले प्रमाणपत्र लिया और एक पीईएम फ़ाइल है, जो openssl ठीक पढ़ता में रख: वास्तव में, यहाँ आदेश मैं CA प्रमाणपत्र प्राप्त करने के लिए प्रयोग किया जाता है। यह एक Verisign प्रमाण पत्र है:

Serial number: 35:97:31:87:f3:87:3a:07:32:7e:ce:58:0c:9b:7e:da 
Subject key identifier: 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 
SHA1 fingerprint: F4:A8:0A:0C:D1:E6:CF:19:0B:8C:BC:6F:BC:99:17:11:D4:82:C9:D0 

कोई भी विचार सत्यापन के साथ काम करने के तरीके को कैसे सक्षम किया जाए?

+0

verisign.pem में कौन सा प्रमाणपत्र है? सुनिश्चित करें कि यह 'ए 1: डीबी: 63: 9 3: 91: 6 एफ: 17: ई 4: 18: 55: 09: 40: 04: 15: सी 7: 02: 40: बी 0: एई: 6 बी के एसएचए 1 फिंगरप्रिंट के साथ प्रमाण पत्र है '(कक्षा 3 सार्वजनिक प्राथमिक प्रमाणन प्राधिकरण) और' 4E: बी 6: डी 5: 78: 49: 9 बी: 1 सी: सीएफ: 5 एफ: 58: 1 ई: एडी: 56: बीई: 3 डी: 9 बी: 67: 44 : ए 5: ई 5' (वेरीसाइन क्लास 3 पब्लिक प्राइमरी सर्टिफिकेशन अथॉरिटी - जी 5) –

+0

मुझे अंत में मिला कि यह एक और यह काम करता है, धन्यवाद! आप कैसे बता सकते हैं कि कौन सा रूट प्रमाणपत्र उपयोग किया जा रहा है? मैं श्रृंखला में प्रत्येक प्रमाण डंप करने के लिए openssl x509 कमांड का उपयोग कर रहा हूं। उनमें से ज्यादातर कहते हैं कि किस प्रमाणपत्र पर हस्ताक्षर किए गए थे, लेकिन मुझे नहीं पता कि आखिरी व्यक्ति कहता है कि किस रूट प्रमाण पर हस्ताक्षर किए गए थे। – abjennings

उत्तर

26

समस्या के कारण के बारे में टिप्पणी को संक्षेप में और अधिक विस्तार में वास्तविक समस्या की व्याख्या करने के लिए:

[0] 54:7D:B3:AC:BF:... /CN=*.s3.amazonaws.com 
[1] 5D:EB:8F:33:9E:... /CN=VeriSign Class 3 Secure Server CA - G3 
[2] F4:A8:0A:0C:D1:... /CN=VeriSign Class 3 Public Primary Certification Authority - G5 
[OT] A1:DB:63:93:91:... /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority 

:

आप OpenSSL ग्राहक आपको निम्न प्राप्त के लिए विश्वास श्रृंखला की जांच पहला प्रमाणपत्र [0] सर्वर द्वारा भेजा गया पत्ता प्रमाण पत्र है। निम्नलिखित प्रमाण पत्र [1] और [2] सर्वर द्वारा भेजे गए चेन प्रमाणपत्र हैं। अंतिम प्रमाणपत्र [ओटी] विश्वसनीय रूट प्रमाणपत्र है, जो सर्वर द्वारा नहीं भेजा जाता है लेकिन विश्वसनीय सीए के स्थानीय भंडारण में है। श्रृंखला में प्रत्येक प्रमाणपत्र अगले एक द्वारा हस्ताक्षरित है और अंतिम प्रमाणपत्र [ओटी] भरोसा है, इसलिए ट्रस्ट श्रृंखला पूरी हो गई है।

आप के बजाय एक ब्राउज़र (जैसे गूगल क्रोम एनएसएस लाइब्रेरी का उपयोग) द्वारा विश्वास श्रृंखला को चेक करते हैं तो आपको निम्न श्रृंखला मिलती है:

[0] 54:7D:B3:AC:BF:... /CN=*.s3.amazonaws.com 
[1] 5D:EB:8F:33:9E:... /CN=VeriSign Class 3 Secure Server CA - G3 
[NT] 4E:B6:D5:78:49:... /CN=VeriSign Class 3 Public Primary Certification Authority - G5 

यहाँ [0] और [1] फिर से सर्वर द्वारा भेजे जाते हैं , लेकिन [एनटी] विश्वसनीय रूट प्रमाणपत्र है। हालांकि यह इस विषय से श्रृंखला प्रमाण पत्र की तरह दिखता है [2] फिंगरप्रिंट कहता है कि प्रमाण पत्र अलग हैं। यदि आप सर्टिफिकेट [2] और [एनटी] पर नज़र डालेंगे तो आप देखेंगे कि प्रमाण पत्र के अंदर सार्वजनिक कुंजी समान है और इस प्रकार दोनों [2] और [NT] का उपयोग हस्ताक्षर को सत्यापित करने के लिए किया जा सकता है [ 1] और इस प्रकार ट्रस्ट चेन बनाने के लिए इस्तेमाल किया जा सकता है।

इसका मतलब है कि, सर्वर सभी मामलों में एक ही प्रमाण पत्र श्रृंखला भेजता है, जबकि एक विश्वसनीय रूट प्रमाणपत्र में श्रृंखला को सत्यापित करने के कई तरीके हैं। यह कैसे किया जाता है एसएसएल पुस्तकालय पर और ज्ञात विश्वसनीय रूट प्रमाणपत्रों पर निर्भर करता है:

      [0] (*.s3.amazonaws.com) 
          | 
          [1] (Verisign G3) --------------------------\ 
          |           | 
     /------------------ [2] (Verisign G5 F4:A8:0A:0C:D1...)   | 
     |                | 
     |    certificates sent by server      | 
.....|...............................................................|................ 
     |    locally trusted root certificates    | 
     |                | 
    [OT] Public Primary Certification Authority  [NT] Verisign G5 4E:B6:D5:78:49 
    OpenSSL library         Google Chrome (NSS library) 

लेकिन सवाल है, बनी हुई है जिनकी वजह से आपके सत्यापन विफल हुआ। आपने जो किया वह ब्राउज़र द्वारा उपयोग किए गए विश्वसनीय रूट प्रमाणपत्र (Verisign G5 4E: B6: D5: 78: 49) ओपनएसएसएल के साथ किया गया था।लेकिन ब्राउज़र (एनएसएस) और ओपनएसएसएल में सत्यापन थोड़ा अलग काम करता है:

  • एनएसएस: सर्वर द्वारा भेजे गए प्रमाणपत्रों से ट्रस्ट श्रृंखला बनाएं। जब हमें स्थानीय रूप से भरोसेमंद रूट प्रमाणपत्रों द्वारा हस्ताक्षरित प्रमाण पत्र प्राप्त होता है तो श्रृंखला का निर्माण करना बंद करें।
  • ओपनएसएसएल_ सर्वर द्वारा भेजे गए प्रमाणपत्रों से ट्रस्ट श्रृंखला बनाएं। ऐसा करने के बाद जांच करें कि क्या हमारे पास श्रृंखला में नवीनतम प्रमाणपत्र पर हस्ताक्षर करने वाला एक विश्वसनीय रूट प्रमाणपत्र है।

इस सूक्ष्म अंतर के कारण ओपनएसएसएल रूट प्रमाण पत्र [एनटी] के खिलाफ श्रृंखला [0], [1], [2] को सत्यापित करने में सक्षम नहीं है, क्योंकि यह प्रमाणपत्र श्रृंखला [2] में नवीनतम तत्व पर हस्ताक्षर नहीं करता है ] लेकिन इसके बजाय [1]। अगर सर्वर ने केवल [0] की एक श्रृंखला भेजी होगी, [1] तो सत्यापन सफल होगा।

यह long known bug है और patches मौजूद है और उम्मीद है कि यदि अंततः X509_V_FLAG_TRUSTED_FIRST विकल्प के परिचय के साथ ओपनएसएसएल 1.0.2 में संबोधित किया गया तो समस्या है।

+0

यह एक उत्कृष्ट उत्तर है और मैंने इसे सही के रूप में चिह्नित किया है। धन्यवाद! मेरी वास्तविक गलती प्रमाणित हो रही थी [2] और उम्मीद है कि श्रृंखला को सत्यापित करने के लिए ([0] और [1] भी कोशिश की गई)। मैंने सोचा [2] एक रूट प्रमाण था। मुझे [ओटी] देखने के लिए नहीं पता था या कहां मिलना है। एक बार जब आपने मुझे फिंगरप्रिंट बताया, तो मैंने इसे /usr/local/share/certs/ca-root-nss.crt (फ्रीबीएसडी) में पाया, लेकिन मैं इसे फ़ायरफ़ॉक्स में भी ढूंढ सकता था या इसे Verisign से डाउनलोड कर सकता था। लेकिन आप कैसे जानते थे कि कौन सा रूट प्रमाण सही था? क्या ब्राउज़र उन्हें जारीकर्ता स्ट्रिंग द्वारा पहचानते हैं? – abjennings

+0

ओपनएसएसएल जारीकर्ता स्ट्रिंग द्वारा खोज करता है और फिर हस्ताक्षर मिलान करता है तो जांच करता है। –

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