Python ร้องขอส่ง SSLError


350

ฉันกำลังทำงานกับสคริปต์ง่าย ๆ ที่เกี่ยวข้องกับ CAS, การตรวจสอบความปลอดภัย jspring, การเปลี่ยนเส้นทางและอื่น ๆ ฉันต้องการใช้ python ของ Kenneth Reitz เพราะมันเป็นงานที่ยอดเยี่ยม! อย่างไรก็ตาม CAS ต้องได้รับการตรวจสอบความถูกต้องผ่าน SSL ดังนั้นฉันต้องผ่านขั้นตอนนั้นก่อน ฉันไม่รู้ว่าคำขอ Python ต้องการอะไร ใบรับรอง SSL นี้ควรอยู่ที่ไหน

Traceback (most recent call last):
  File "./test.py", line 24, in <module>
  response = requests.get(url1, headers=headers)
  File "build/bdist.linux-x86_64/egg/requests/api.py", line 52, in get
  File "build/bdist.linux-x86_64/egg/requests/api.py", line 40, in request
  File "build/bdist.linux-x86_64/egg/requests/sessions.py", line 209, in request 
  File "build/bdist.linux-x86_64/egg/requests/models.py", line 624, in send
  File "build/bdist.linux-x86_64/egg/requests/models.py", line 300, in _build_response
  File "build/bdist.linux-x86_64/egg/requests/models.py", line 611, in send
requests.exceptions.SSLError: [Errno 1] _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

คุณสามารถแบ่งปันข้อมูลรหัสเพิ่มเติมได้หรือไม่ ดูเหมือนว่ามีขั้นตอนที่ขาดหายไป
TankorSmash

5
คุณควรพูดถึงซอฟต์แวร์เวอร์ชันที่คุณต้องการความช่วยเหลือเสมอ
Piotr Dobrogost

ฉันเจอปัญหานี้โดยที่ฉันใช้ python 3.5 tornado 4.4 HTTPRequest ตั้งค่า validate_cert = True เพื่อให้คุณตั้งค่า False เพื่อจัดการมัน
pan7an

ลองทำดังนี้: requests.get (' example.com ', Verify = certifi.where ())
Nei

คำตอบ:


460

ปัญหาที่คุณมีเกิดจากใบรับรอง SSL ที่ไม่น่าเชื่อถือ

เช่นเดียวกับ @dirk ที่กล่าวถึงในความคิดเห็นก่อนหน้าการแก้ไขที่เร็วที่สุดคือการตั้งค่าverify=False:

requests.get('https://example.com', verify=False)

โปรดทราบว่านี่จะทำให้ใบรับรองไม่ได้รับการยืนยัน วิธีนี้จะทำให้แอปพลิเคชันของคุณเสี่ยงต่อความปลอดภัยเช่นการโจมตีจากคนกลาง

แน่นอนใช้การตัดสิน ตามที่ระบุไว้ในความคิดเห็นที่นี้อาจจะเป็นที่ยอมรับสำหรับการใช้งาน / ใบปลิวอย่างรวดเร็ว / สคริปต์แต่มันไม่ควรจะไปที่ซอฟแวร์การผลิต

หากการข้ามการตรวจสอบใบรับรองไม่เป็นที่ยอมรับในบริบทเฉพาะของคุณให้พิจารณาตัวเลือกต่อไปนี้ตัวเลือกที่ดีที่สุดของคุณคือการตั้งค่า verifyพารามิเตอร์เป็นสตริงที่เป็นเส้นทางของ.pemไฟล์ใบรับรอง (ซึ่งคุณควรได้รับจากการรักษาความปลอดภัยบางประเภท วิธีการ)

ดังนั้นในเวอร์ชัน 2.0 verifyพารามิเตอร์จึงยอมรับค่าต่อไปนี้โดยมีความหมายตามลำดับ:

  • True: ทำให้ใบรับรองตรวจสอบกับหน่วยงานออกใบรับรองที่เชื่อถือได้ของไลบรารี (หมายเหตุ: คุณสามารถดูว่าคำขอใบรับรองรูทใดที่ใช้ผ่านห้องสมุด Certifi ซึ่งเป็นฐานข้อมูลที่เชื่อถือได้ของ RC ที่แยกจากคำขอ: Certifi - ฐานข้อมูลที่เชื่อถือสำหรับมนุษย์ )
  • False: ข้ามการตรวจสอบใบรับรอง สมบูรณ์
  • พา ธ ไปยังไฟล์ CA_BUNDLE เพื่อให้คำขอใช้ตรวจสอบใบรับรอง

ที่มา: คำขอ - การตรวจสอบใบรับรอง SSL

ลองดูที่certพารามิเตอร์ในลิงค์เดียวกัน


1
ใช่เมื่อฉันใช้ dotCloud ในอูบุนตู "การตรวจสอบใบรับรองล้มเหลว" เดียวกันก็ออกมา หลังจากแก้ไข "requests.session (ส่วนหัว = ส่วนหัว, hooks = hooks, ตรวจสอบ = False)" ใน "/usr/local/lib/python2.6/dist-packages/dotcloud/client/client.py"
diyism

2
สิ่งนี้ไม่ได้ทำเครื่องหมายว่าถูกต้อง แต่ฉันสามารถยืนยันได้ว่ามันใช้งานได้ (ตรงข้ามกับคำตอบด้านล่าง)
khalid13

40
@ khalid13: ขวาน "ทำงาน" เป็นยาแก้ปวดหัว (ไม่มีหัว - ไม่ปวดหัว) ไม่ได้หมายความว่าควรใช้อย่างนั้น verify=Falseปิดใช้งานการตรวจสอบใบรับรอง SSL ของโฮสต์
jfs

24
@JFSebastian สุจริตขึ้นอยู่กับสิ่งที่คุณทำ สำหรับแอปพลิเคชั่นด่วน / การโยนทิ้งของฉันมันมากเกินพอ
khalid13

5
@diyism การเปลี่ยนแปลงดังกล่าวฟังดูไม่ปลอดภัยมาก ...
binki

111

จากเอกสารการร้องขอเกี่ยวกับการตรวจสอบ SSL :

คำขอสามารถตรวจสอบใบรับรอง SSL สำหรับคำขอ HTTPS ได้เช่นเดียวกับเว็บเบราว์เซอร์ ในการตรวจสอบใบรับรอง SSL ของโฮสต์คุณสามารถใช้อาร์กิวเมนต์ตรวจสอบ:

>>> requests.get('https://kennethreitz.com', verify=True)

หากคุณไม่ต้องการยืนยันใบรับรอง SSL ของคุณ verify=False


4
ดีฉันเพิ่มการตรวจสอบ = จริง แต่ก็ยังได้รับข้อผิดพลาดเดียวกันแน่นอน ไม่มีการเปลี่ยนแปลง. ต้องมีอย่างอื่นที่จำเป็น แต่ไม่รู้ว่ามันจะเป็นอะไร
TedBurrows

ฉันคิดว่าตอนนี้ฉันได้ลงสู่ความบ้าคลั่ง SSL ฉันเพิ่มสิ่งนี้ในการรับครั้งแรกของฉัน ... รับ (url1, ส่วนหัว = ส่วนหัว, cert = '/ etc / pki / tls / cert.pem', ตรวจสอบ = True, config = my_config) ดังนั้นตอนนี้ฉันได้รับข้อผิดพลาดนี้ requests.exceptions.SSLError: [Errno 336265225] _ssl.c: 351: ข้อผิดพลาด: 140B0009: กิจวัตร SSL: SSL_CTX_use_PrivateKey_file: PEM lib ฉันไม่ได้รู้ว่าสิ่งนี้หมายถึงอะไร
TedBurrows

14
เพียงแค่ตั้งค่าการตรวจสอบ = เท็จหากคุณไม่ต้องการตรวจสอบใบรับรองฉันจะทำอย่างไรถ้าคุณมีใบรับรองที่ลงนามด้วยตนเอง
Dirk

16
หากคุณมีใบรับรองแบบลงนามด้วยตนเองให้ดาวน์โหลดและตั้งค่าการยืนยันเป็นชื่อไฟล์ ไม่มีข้อแก้ตัวใด ๆ สำหรับการตั้งค่า Verify = False ยืนยัน = '/ path / to / cert.pem'
Matthias Urlichs

14
ขออภัยฉันต้องการลงคะแนนให้กับคำตอบนี้เนื่องจากคำขอไม่จัดการคำขอ HTTPS "เช่นเว็บเบราว์เซอร์" หากความน่าเชื่อถือ SSL เชนทั้งหมด (รวมถึงใบรับรองระดับกลาง) ไม่ได้ถูกประกาศบนเซิร์ฟเวอร์และต้องการการดาวน์โหลดใบรับรองเพิ่มเติมคุณจะได้รับข้อผิดพลาดการตรวจสอบ SSL ด้านบน เว็บเบราว์เซอร์จะทำการดาวน์โหลดเพิ่มเติมและไม่ตั้งค่าสถานะข้อผิดพลาดใบรับรองใด ๆ นี่เป็นวิธีหนึ่งที่เว็บเบราว์เซอร์และคำขอแตกต่างกัน มีคนอื่น ๆ คำขอทำการยืนยันบางอย่าง แต่ก็ไม่ดีเท่าเบราว์เซอร์
Louis Cremen

53

ชื่อของไฟล์ CA ที่คุณสามารถใช้ผ่านverify:

cafile = 'cacert.pem' # http://curl.haxx.se/ca/cacert.pem
r = requests.get(url, verify=cafile)

ถ้าคุณใช้verify=Trueแล้วrequestsใช้ชุด CA ของตัวเองที่ไม่อาจมี CA ที่ลงนามในใบรับรองเซิร์ฟเวอร์ของคุณ


12
@ 9emE0iL18gxCqLT: ทำไมคุณคิดว่าระบบทั้งหมดใช้เส้นทางที่คุณให้มา requestsสามารถบรรจุสำหรับการกระจายของคุณ วิ่งpython -mrequests.certsไปหาจุดที่มันชี้ไป
jfs

3
หากชุด cacert ของคำขอ Python ล้าสมัยฉันจะอัพเดตได้อย่างไร
CMCDragonkai

5
คุณไม่ควรใช้สิ่งนั้นcacert.pemจากการม้วนงอ มันมี certs ที่ถูกเพิกถอนจำนวนมาก ตรวจสอบ Certifi (ซึ่งคำขอใช้): certifi.io
Kenneth Reitz

3
@ KennethReitz: 1- สิ่งที่คำขอใช้ล้มเหลวสำหรับ OP (ไม่เช่นนั้นไม่มีคำถาม) 2- cacert.pemคือใบรับรอง CA ที่แยกจาก Mozilla (โดย cURL) - เป็นเพียงตัวอย่าง (ถ้ารายการ CA ที่ใช้โดยเว็บยอดนิยม - เบราว์เซอร์ไม่สามารถใช้เป็นตัวอย่างจากนั้นฉันไม่รู้ว่าจะเป็นอะไร) - จุดคำตอบที่คุณสามารถส่งไฟล์ CA ของคุณเองหากรายการเริ่มต้นล้มเหลว
jfs

คุณสามารถทำสิ่งนี้และใช้ใบรับรองไคลเอ็นต์ในเวลาเดียวกันได้หรือไม่ ฉันกำลังมีปัญหากับสิ่งนี้
user1156544

42

$ pip install -U requests[security]

  • ทดสอบบน Python 2.7.6 @ Ubuntu 14.04.4 LTS
  • ทดสอบกับ Python 2.7.5 @ MacOSX 10.9.5 (Mavericks)

เมื่อคำถามนี้ถูกเปิด (2012-05) เวอร์ชันของคำขอคือ 0.13.1 ในเวอร์ชัน2.4.1 (2014-09)มีการแนะนำพิเศษ "ความปลอดภัย" โดยใช้certifiแพ็คเกจหากมี

ตอนนี้ (2016-09) รุ่นหลักคือ 2.11.1 ที่ทำงานที่ดีได้โดยไม่ต้อง verify=Falseไม่จำเป็นต้องใช้requests.get(url, verify=False)ถ้าติดตั้งพร้อมrequests[security]บริการเสริม


7
แก้ไขโดย pip install -U requests[security] --no-cacheสองครั้งและpip install certifi==2015.04.28
Aamir Abro

@alanjds จะทำอย่างไรถ้าฉันต้องการกำหนดค่าไพ ธ อนเพื่อเชื่อถือ ssl cert หรือปิดใช้งานการตรวจสอบใบรับรอง แต่อยู่ในสภาพแวดล้อมโดยไม่ต้องแก้ไขซอร์สโค้ด? ตัวอย่างเช่นถ้าฉันดาวน์โหลดยูทิลิตี้ Python ที่มีอยู่ (เช่น AWS CLI) และฉันต้องการเชื่อถือ certs หรือเพิกเฉยต่อการตรวจสอบความถูกต้องใบรับรองสำหรับเครื่องมือเหล่านั้นหรือไม่
Howiecamp

@ Howiecamp จากนั้นคุณสามารถไปผ่านคำตอบ jf-sebastian ฉันเดา: stackoverflow.com/a/12865159/798575
alanjds

@alanjds แต่คำตอบของเขาไม่ถือว่าฉันเขียนรหัสและ / หรือมีการเข้าถึงรหัสหรือไม่ ฉันต้องการนำสิ่งนี้ไปใช้ในระดับสภาพแวดล้อม
Howiecamp

3
ทำpip install --upgrade pipก่อนที่จะติดตั้งแพคเกจความปลอดภัยร้องขอเพื่อหลีกเลี่ยงข้อผิดพลาดอื่น ๆ
Vincent Claes

40

ฉันพบปัญหาเดียวกันและการตรวจสอบใบรับรอง SSL ล้มเหลวปัญหาเมื่อใช้ aws boto3 โดยตรวจสอบรหัส boto3 ฉันพบREQUESTS_CA_BUNDLEว่าไม่ได้ตั้งค่าดังนั้นฉันจึงแก้ไขปัญหาทั้งสองด้วยการตั้งค่าด้วยตนเอง:

from boto3.session import Session
import os

# debian
os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(
    '/etc/ssl/certs/',
    'ca-certificates.crt')
# centos
#   'ca-bundle.crt')

สำหรับ aws-cli ฉันเดาว่าการตั้งค่า REQUESTS_CA_BUNDLE ใน~/.bashrcจะแก้ไขปัญหานี้ (ไม่ได้ทดสอบเพราะ aws-cli ของฉันทำงานได้โดยไม่ต้องใช้)

REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt # ca-bundle.crt
export REQUESTS_CA_BUNDLE

2
นี่เป็นการแก้ไขปัญหาของฉัน! ฉันใช้ Charles Proxy บน Mac เพื่อดีบักไลบรารีที่ทำให้ JSON โทรไปยัง HTTPS API ฉันติดตั้งใบรับรอง Charless ตามที่ระบุเพิ่มไปยังพวงกุญแจ แต่ Python ยังคงล้มเหลวด้วย: SSLError: ("handshake ไม่ดี: ข้อผิดพลาด ([('SSL ประจำ', 'ssl3_get_server_certificate', 'ใบรับรองการตรวจสอบล้มเหลว')]," ,) ในการแก้ไขปัญหานี้ฉันได้ทำตามคำแนะนำของคุณเกี่ยวกับการเพิ่ม REQUESTS_CA_BUNDLE และส่งออกใบรับรอง Charles จากพวงกุญแจของฉันเป็นไฟล์. pem ตอนนี้มันใช้งานได้!
mallyvai

ขอบคุณปัญหาเดียวกันนี้เกิดขึ้นกับ Fiddler ที่เปิด
user565447

@ user565447 ฉันพยายามที่จะทำงานกับ Fiddler ในขณะนี้ ควรตั้งค่า REQUESTS_CA_BUNDLE เป็นใบรับรองของ Fiddler ไหม
Howiecamp

19

ในกรณีที่คุณมีห้องสมุดที่ต้องพึ่งพาrequestsและคุณไม่สามารถปรับเปลี่ยนพา ธ การตรวจสอบ (เช่นเดียวกับpyvmomi) คุณจะต้องค้นหาcacert.pemบันเดิลพร้อมคำขอและผนวก CA ของคุณที่นั่น นี่เป็นวิธีการทั่วไปในการค้นหาcacert.pemสถานที่:

หน้าต่าง

C:\>python -c "import requests; print requests.certs.where()"
c:\Python27\lib\site-packages\requests-2.8.1-py2.7.egg\requests\cacert.pem

ลินุกซ์

#  (py2.7.5,requests 2.7.0, verify not enforced)
root@host:~/# python -c "import requests; print requests.certs.where()"
/usr/lib/python2.7/dist-packages/certifi/cacert.pem

#  (py2.7.10, verify enforced)
root@host:~/# python -c "import requests; print requests.certs.where()"
/usr/local/lib/python2.7/dist-packages/requests/cacert.pem

BTW @ คำร้องขอ -evs การรวม cacerts ของคุณกับคำขอเป็นเรื่องที่น่ารำคาญจริงๆ ... โดยเฉพาะอย่างยิ่งความจริงที่ว่าคุณไม่ได้ใช้ระบบ ca store ก่อนและนี่ไม่ใช่เอกสารที่ใดก็ได้

ปรับปรุง

ในสถานการณ์ที่คุณใช้ห้องสมุดและไม่มีการควบคุมตำแหน่ง ca-bundle คุณสามารถกำหนดตำแหน่ง ca-bundle ให้เป็น ca-bundle ทั่วทั้งโฮสต์ของคุณได้:

REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt python -c "import requests; requests.get('https://somesite.com';)"

ร้อยครั้งนี้: คีย์ไม่สามารถแก้ไขverifyพา ธ
ghukill

ถ้าคุณใช้ใบรับรองที่ลงชื่อด้วยตนเอง CA จะเป็นอย่างไรในกรณีนั้น
user1114

การอัพเดทเล็ก ๆ - สำหรับ python 3.6 ควรมีวงเล็บสำหรับคำสั่งพิมพ์ - python -c "คำขอนำเข้า; print (requests.certs.where ())"
1114

15

ฉันประสบปัญหาเดียวกันโดยใช้ gspread และคำสั่งเหล่านี้ใช้ได้สำหรับฉัน:

sudo pip uninstall -y certifi
sudo pip install certifi==2015.04.28

มันทำเพื่อฉัน ขอบคุณ :)
alex-mcleod

4
นี่เป็นข้อเสียของการติดตั้งใบรับรองที่ถูกเพิกถอนหรือไม่น่าเชื่อถือจากใบรับรองรุ่นเก่าไม่แนะนำ
dragon788

ถ้าด้วยเหตุผลบางอย่างคุณถูกบังคับให้ยึดติดกับ python 2.7 เวอร์ชันแรกใบรับรองการปรับลดรุ่นเป็นวิธีเดียวที่ใช้ได้ผลสำหรับฉัน
seans

15

หากคุณต้องการลบคำเตือนให้ใช้รหัสด้านล่าง

import urllib3

urllib3.disable_warnings()

และverify=Falseด้วยrequest.getหรือpostวิธีการ


12

ฉันพบวิธีการเฉพาะในการแก้ไขปัญหาที่คล้ายกัน แนวคิดคือชี้ไฟล์ cacert ที่เก็บไว้ในระบบและใช้โดยแอปพลิเคชันที่ใช้ ssl อื่น

ใน Debian (ฉันไม่แน่ใจว่าเหมือนกันในดิสทริบิวชันอื่น ๆ ) ไฟล์ใบรับรอง (.pem) ถูกเก็บไว้ที่/etc/ssl/certs/ดังนั้นนี่คือรหัสที่เหมาะกับฉัน:

import requests
verify='/etc/ssl/certs/cacert.org.pem'
response = requests.get('https://lists.cacert.org', verify=verify)

สำหรับการคาดเดาpemไฟล์ที่เลือกฉันได้เรียกดู url และตรวจสอบว่า Certificate Authority (CA) สร้างใบรับรองใด

แก้ไข: หากคุณไม่สามารถแก้ไขรหัส (เพราะคุณใช้แอพที่สาม) คุณสามารถลองเพิ่มpemใบรับรองลงในโดยตรง/usr/local/lib/python2.7/dist-packages/requests/cacert.pem(เช่นการคัดลอกไปที่ท้ายไฟล์)


2
โพสต์ที่เกี่ยวข้องสำหรับการดีบัก CA_BUNDLE ที่ใช้โดย python
chk

สิ่งที่เกี่ยวกับการแทนที่/usr/local/lib/python2.7/dist-packages/requests/cacert.pemด้วย symlink ไปยังร้านค้า OS?
CMCDragonkai

8

verify=Falseหากคุณไม่ได้กังวลเกี่ยวกับใบรับรองเพียงแค่ใช้

import requests

url = "Write your url here"

returnResponse = requests.get(url, verify=False)

7

หลังจากชั่วโมงของการดีบักฉันสามารถใช้งานได้เฉพาะกับแพ็คเกจต่อไปนี้:

requests[security]==2.7.0  # not 2.18.1
cryptography==1.9  # not 2.0

การใช้ OpenSSL 1.0.2g 1 Mar 2016

ไม่มีแพ็คเกจเหล่านี้ verify=Falseก็ไม่สามารถใช้งานได้

ฉันหวังว่านี่จะช่วยให้ใครบางคน


5

ฉันพบปัญหาเดียวกัน กลายเป็นว่าฉันไม่ได้ติดตั้งใบรับรองระดับกลางบนเซิร์ฟเวอร์ของฉัน (เพียงต่อท้ายใบรับรองของคุณตามที่เห็นด้านล่าง)

https://www.digicert.com/ssl-support/pem-ssl-creation.htm

ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้งแพ็คเกจใบรับรอง CA:

sudo apt-get install ca-certificates

การอัปเดตเวลาอาจแก้ไขปัญหานี้ได้:

sudo apt-get install ntpdate
sudo ntpdate -u ntp.ubuntu.com

หากคุณใช้ใบรับรองที่ลงชื่อด้วยตนเองคุณอาจต้องเพิ่มใบรับรองลงในระบบของคุณด้วยตนเอง


หมายเหตุสิ่งนี้ใช้ได้กับการติดตั้งคำขอผ่าน apt-get ซึ่งได้รับการแก้ไขโดย Debian / Ubuntu เพื่อใช้ certs ระบบ ขอเรือที่เหมาะสมพร้อมด้วย curated ของมันเองอย่างระมัดระวัง, กลุ่ม CA: certifi.io
Kenneth Reitz

CA รูทควรจะไม่เพียงพอหรือไม่ ทำไมคุณถึงต้องการคนกลาง
timmy

5

หากการเรียกใช้การร้องขอนั้นถูกฝังอยู่ลึกลงไปในรหัสและคุณไม่ต้องการติดตั้งใบรับรองเซิร์ฟเวอร์จากนั้นเพียงเพื่อจุดประสงค์ในการดีบักเท่านั้นเป็นไปได้ที่จะส่งคำร้องขอ Monkeypatch:

import requests.api
import warnings


def requestspatch(method, url, **kwargs):
    kwargs['verify'] = False
    return _origcall(method, url, **kwargs)

_origcall = requests.api.request
requests.api.request = requestspatch
warnings.warn('Patched requests: SSL verification disabled!')

อย่าใช้ในการผลิต!


4

สายไปงานปาร์ตี้ฉันเดา แต่ฉันต้องการวางการแก้ไขสำหรับคนจรจัดเหมือนตัวเอง! ดังนั้นต่อไปนี้ใช้งานได้กับฉันใน Python 3.7.x

พิมพ์สิ่งต่อไปนี้ในเทอร์มินัลของคุณ

pip install --upgrade certifi      # hold your breath..

ลองเรียกใช้สคริปต์ / คำขอของคุณอีกครั้งและดูว่ามันใช้งานได้หรือไม่ (ฉันแน่ใจว่ามันจะไม่ได้รับการแก้ไข!) หากไม่ได้ผลให้ลองใช้คำสั่งต่อไปนี้ในเทอร์มินัลโดยตรง

open /Applications/Python\ 3.6/Install\ Certificates.command  # please replace 3.6 here with your suitable python version

3

ฉันต่อสู้ปัญหานี้เป็นเวลาชั่วโมง

ฉันพยายามอัพเดทคำขอ จากนั้นฉันก็อัพเดท certifi ฉันชี้ตรวจสอบเพื่อ certifi.where () (รหัสทำตามนี้เริ่มต้น anyways) ไม่มีอะไรทำงาน

ในที่สุดฉันก็อัพเดตเวอร์ชั่นของ python เป็น python 2.7.11 ฉันใช้ Python 2.7.5 ซึ่งเข้ากันไม่ได้กับวิธีการตรวจสอบใบรับรอง เมื่อฉันอัพเดท Python (และการอ้างอิงอื่น ๆ จำนวนหนึ่ง) มันก็เริ่มทำงานได้


หากคุณอัปเดต OpenSSL เป็นรุ่น> 1.0.1 แล้วอาจเป็นปัญหาได้ ดูคำตอบของฉันร้อง stackoverflow.com/a/44543047/1413201
Tim Ludwinski

การเปลี่ยนจาก Python 2.7.9 เป็น 2.7.10 ได้แก้ไขสิ่งนี้ให้ฉัน
crazystick

3

นี่คล้ายกับคำตอบของ @ rafael-almeida แต่ฉันต้องการชี้ให้เห็นว่าตามคำร้องขอ 2.11+ ไม่มีค่า 3 ค่าที่verifyสามารถทำได้มีจริง 4:

  • True: ตรวจสอบกับ CA ที่เชื่อถือได้ภายในของคำขอ
  • False: ข้ามการตรวจสอบใบรับรองสมบูรณ์ (ไม่แนะนำ)
  • พา ธ ไปยังไฟล์ CA_BUNDLE คำขอจะใช้สิ่งนี้เพื่อตรวจสอบใบรับรองของเซิร์ฟเวอร์
  • พา ธ ไปยังไดเร็กทอรีที่มีไฟล์ใบรับรองพับลิก คำขอจะใช้สิ่งนี้เพื่อตรวจสอบใบรับรองของเซิร์ฟเวอร์

คำตอบที่เหลือของฉันคือ # 4 วิธีใช้ไดเรกทอรีที่มีใบรับรองเพื่อตรวจสอบความถูกต้อง:

รับใบรับรองสาธารณะที่จำเป็นและวางไว้ในไดเรกทอรี

พูดอย่างเคร่งครัดคุณอาจ "ควร" ใช้วิธีการนอกวงรับใบรับรอง แต่คุณสามารถดาวน์โหลดได้โดยใช้เบราว์เซอร์ใดก็ได้

หากเซิร์ฟเวอร์ใช้สายใบรับรองให้ตรวจสอบให้แน่ใจว่าได้รับใบรับรองทุกใบในสายโซ่

ตามเอกสารการร้องขอไดเรกทอรีที่มีใบรับรองจะต้องถูกประมวลผลด้วยยูทิลิตี้ "rehash" ( openssl rehash)

(สิ่งนี้ต้องใช้ openssl 1.1.1+ และไม่ใช่ทั้งหมดสำหรับ Windows openssl ที่สนับสนุนการทำ rehash หากopenssl rehashไม่ได้ผลสำหรับคุณคุณสามารถลองเรียกใช้สคริปต์ rubash ruby ​​ที่https://github.com/ruby/openssl/blob/master /sample/c_rehash.rbแม้ว่าฉันจะไม่ได้ลอง)

ฉันมีปัญหาในการรับคำขอเพื่อรับรองใบรับรองของฉัน แต่หลังจากฉันใช้openssl x509 -outform PEMคำสั่งเพื่อแปลง certs เป็น Base64.pemรูปแบบทุกอย่างทำงานได้อย่างสมบูรณ์

นอกจากนี้คุณยังสามารถทำการเชื่องช้าสันหลังยาว:

try:
    # As long as the certificates in the certs directory are in the OS's certificate store, `verify=True` is fine.
    return requests.get(url, auth=auth, verify=True)
except requests.exceptions.SSLError:
    subprocess.run(f"openssl rehash -compat -v my_certs_dir", shell=True, check=True)
    return requests.get(url, auth=auth, verify="my_certs_dir")

2

ขณะนี้มีปัญหาในโมดูลคำขอที่ก่อให้เกิดข้อผิดพลาดนี้ปรากฏใน v2.6.2 ถึง v2.12.4 (ATOW): https://github.com/kennethreitz/requests/issues/2573

วิธีแก้ปัญหาสำหรับปัญหานี้กำลังเพิ่มบรรทัดต่อไปนี้: requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS'


FWIW มันยังคงมีการร้องขอ == 2.13.0 วิธีแก้ปัญหาข้างต้นแก้ไขได้ยัง
Tamás Szelei

1

ตามที่ @Rafael Almeida กล่าวถึงปัญหาที่คุณมีเกิดจากใบรับรอง SSL ที่ไม่น่าเชื่อถือ ในกรณีของฉันใบรับรอง SSL ไม่น่าเชื่อถือโดยเซิร์ฟเวอร์ของฉัน เพื่อหลีกเลี่ยงปัญหานี้โดยไม่ส่งผลต่อความปลอดภัยฉันดาวน์โหลดใบรับรองและติดตั้งลงบนเซิร์ฟเวอร์ (เพียงแค่ดับเบิลคลิกที่ไฟล์. crt แล้วติดตั้งใบรับรอง ... )


0

ไม่สามารถเพิ่มตัวเลือกได้หากมีการเรียกคำขอจากแพ็คเกจอื่น ในกรณีนั้นการเพิ่มใบรับรองไปยังชุด cacert เป็นเส้นทางแบบตรงเช่นฉันต้องเพิ่ม "StartCom Class 1 เซิร์ฟเวอร์หลักระดับกลาง CA" ซึ่งฉันดาวน์โหลดใบรับรองหลักลงใน StartComClass1.pem เนื่องจาก virtualenv ของฉันชื่อ caldav ฉันเพิ่มใบรับรองด้วย:

cat StartComClass1.pem >> .virtualenvs/caldav/lib/python2.7/site-packages/pip/_vendor/requests/cacert.pem
cat temp/StartComClass1.pem >> .virtualenvs/caldav/lib/python2.7/site-packages/requests/cacert.pem

หนึ่งในนั้นอาจจะเพียงพอฉันไม่ได้ตรวจสอบ


0

ฉันมีปัญหาการตรวจสอบใบรับรองที่คล้ายกันหรือเหมือนกัน ฉันอ่านว่า OpenSSL เวอร์ชั่นน้อยกว่า 1.0.2 ซึ่งคำขอขึ้นอยู่กับบางครั้งมีปัญหาในการตรวจสอบใบรับรองที่แข็งแกร่ง (ดูที่นี่ ) CentOS 7 ดูเหมือนว่าจะใช้ 1.0.1e ซึ่งดูเหมือนว่าจะมีปัญหา

ฉันไม่แน่ใจว่าจะแก้ไขปัญหานี้บน CentOS ได้อย่างไรดังนั้นฉันจึงตัดสินใจอนุญาตใบรับรอง CA ขนาด 1024 บิตที่อ่อนลง

import certifi # This should be already installed as a dependency of 'requests'
requests.get("https://example.com", verify=certifi.old_where())

ฉันใช้ Python 2.7.10 ที่ติดตั้งโดย ArcGIS และไม่มีโมดูล certifi ติดตั้งอยู่ โมดูลคำร้องขอที่ติดตั้งอยู่ในเวอร์ชัน 2.11.1
ลูคัส

0

ฉันต้องอัพเกรดจาก Python 3.4.0 เป็น 3.4.6

pyenv virtualenv 3.4.6 myvenv
pyenv activate myvenv
pip install -r requirements.txt

0

ในกรณีของฉันเหตุผลนั้นค่อนข้างน่ารำคาญ

ฉันรู้ว่าการตรวจสอบ SSL ใช้งานได้จนกระทั่งไม่กี่วันก่อนหน้านี้และทำงานด้วยเครื่องอื่น

ขั้นตอนต่อไปของฉันคือการเปรียบเทียบเนื้อหาใบรับรองและขนาดระหว่างเครื่องที่การตรวจสอบใช้งานได้และที่ไม่มีการตรวจสอบ

สิ่งนี้นำไปสู่ฉันอย่างรวดเร็วซึ่งระบุว่าใบรับรองในเครื่องทำงานไม่ถูกต้องไม่ดีและเมื่อฉันแทนที่ด้วยใบรับรอง 'ดี' ทุกอย่างก็ใช้ได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.