Как заставить запросы Python доверять самоподписанному сертификату SSL?

88
import requests
data = {'foo':'bar'}
url = 'https://foo.com/bar'
r = requests.post(url, data=data)

Если URL-адрес использует самоподписанный сертификат, это не сработает с

requests.exceptions.SSLError: [Errno 1] _ssl.c:507: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Я знаю, что могу перейти Falseк verifyпараметру, например:

r = requests.post(url, data=data, verify=False)

Однако я бы хотел направить запросы на копию открытого ключа на диске и сказать ему доверять этому сертификату.

Мэтью Мойзен
источник

Ответы:

61

пытаться:

r = requests.post(url, data=data, verify='/path/to/public_key.pem')
Крок
источник
1
Можете ли вы сделать то же самое и одновременно использовать клиентские сертификаты? У меня проблемы с этим.
user1156544
10
Обратите внимание, что передаваемый файл .pem должен включать сертификат сервера и все промежуточные сертификаты . Я потерял несколько часов, пытаясь понять, почему это не сработало после добавления сертификата сервера.
ChrisBob
Я добавил самоподписанный сертификат certificate.pem, и он сработал.
HS
6
У меня эта техника не сработала. Раньше я ssl.get_server_certificateзагружал сертификат для (self-signed.badssl.com, 443), сохранял этот сертификат cert.pem, а затем запускал, requests.get('https://self-signed.badssl.com/', verify='cert.pem')но все равно не получалось с ошибкой SSL (этот сертификат самоподписанный).
Джейсон Р. Кумбс
41

С помощью verifyпараметра вы можете предоставить пакет настраиваемого центра сертификации

requests.get(url, verify=path_to_bundle_file)

Из документов :

Вы можете передать verifyпуть к файлу CA_BUNDLE с сертификатами доверенных центров сертификации. Этот список доверенных центров сертификации также можно указать с помощью переменной среды REQUESTS_CA_BUNDLE.

Д-р Ян-Филип Герке
источник
26

Самый простой - экспортировать переменную, REQUESTS_CA_BUNDLEкоторая указывает на ваш частный центр сертификации или на конкретный пакет сертификатов. В командной строке это можно сделать следующим образом:

export REQUESTS_CA_BUNDLE=/path/to/your/certificate.pem
python script.py

Если у вас есть центр сертификации и вы не хотите вводить его exportкаждый раз, вы можете добавить REQUESTS_CA_BUNDLEего ~/.bash_profileследующим образом:

echo "export REQUESTS_CA_BUNDLE=/path/to/your/certificate.pem" >> ~/.bash_profile ; source ~/.bash_profile
Майк Н
источник
Переменная среды - это то, что мне нужно, чтобы PyCharm работал с сертификатами, хранящимися в файле сертификата OpenSSL.
Брэди
У меня в цепочке есть самоподписанный сертификат. Это решение решило мою проблему с библиотекой boto3.
Илькин
7

Случай, когда требуется несколько сертификатов, был решен следующим образом: объединить несколько корневых файлов pem, myCert-A-Root.pem и myCert-B-Root.pem, в файл. Затем установите запросы REQUESTS_CA_BUNDLE var в этот файл в моем ./.bash_profile.

$ cp myCert-A-Root.pem ca_roots.pem
$ cat myCert-B-Root.pem >> ca_roots.pem
$ echo "export REQUESTS_CA_BUNDLE=~/PATH_TO/CA_CHAIN/ca_roots.pem" >> ~/.bash_profile ; source ~/.bash_profile
Халберт Стоун
источник
Это был мой "аааа" момент дня ... Большое спасибо ... С этой подсказкой я заставил свой самоподписанный сертификат jira работать ... ;-) Я знаю, что есть, возможно, сотни сайтов и ответы, которые описывают это , но я нашел вашу, так что вы получаете мою честь за то, что помогли мне решить мою проблему ... d
alexrjs
4

Настройка export SSL_CERT_FILE=/path/file.crtдолжна делать свою работу.

морщинка
источник
Благодарю. У меня работает ( REQUESTS_CA_BUNDLEв моем случае переменная не действует).
Паскаль Х.
0

Если кто-то случайно приземлится здесь (как это сделал я), желающий добавить CA (в моем случае Charles Proxy) для httplib2, похоже, вы можете добавить его в cacerts.txtфайл, включенный в пакет python.

Например:

cat ~/Desktop/charles-ssl-proxying-certificate.pem >> /usr/local/google-cloud-sdk/lib/third_party/httplib2/cacerts.txt

Переменные среды, на которые есть ссылки в других решениях, кажутся специфичными для запросов и не были обнаружены httplib2 в моем тестировании.

Мэт Шаффер
источник