Jak sprawić, by żądania Pythona ufały certyfikatowi SSL z podpisem własnym?

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

Jeśli adres URL używa certyfikatu z podpisem własnym, kończy się to niepowodzeniem

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

Wiem, że mogę przejść Falsedo verifyparametru tak:

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

Chciałbym jednak skierować żądania do kopii klucza publicznego na dysku i powiedzieć mu, aby ufał temu certyfikatowi.

Matthew Moisen
źródło

Odpowiedzi:

61

próbować:

r = requests.post(url, data=data, verify='/path/to/public_key.pem')
krock
źródło
1
Czy możesz zrobić to samo i używać certyfikatów klienta w tym samym czasie? Mam z tym problemy.
user1156544
10
Należy pamiętać, że przekazywany plik .pem musi zawierać certyfikat serwera i wszelkie certyfikaty pośrednie . Straciłem kilka godzin, próbując dowiedzieć się, dlaczego nie zadziałało po dodaniu certyfikatu serwera.
ChrisBob
Dodałem certyfikat.pem z podpisem własnym i zadziałało.
HS Rathore
6
Ta technika nie działa dla mnie. Kiedyś ssl.get_server_certificatepobierałem certyfikat dla (self-signed.badssl.com, 443), zapisałem go cert.pem, a następnie uruchomiłem requests.get('https://self-signed.badssl.com/', verify='cert.pem')i nadal nie powiodło się z błędem SSL (ten certyfikat jest samopodpisany).
Jason R. Coombs
41

Za pomocą tego verifyparametru można podać niestandardowy pakiet urzędu certyfikacji

requests.get(url, verify=path_to_bundle_file)

Z dokumentów :

Możesz przekazać verifyścieżkę do pliku CA_BUNDLE z certyfikatami zaufanych urzędów certyfikacji. Tę listę zaufanych urzędów certyfikacji można również określić za pomocą zmiennej środowiskowej REQUESTS_CA_BUNDLE.

Dr Jan-Philip Gehrcke
źródło
26

Najłatwiej jest wyeksportować zmienną REQUESTS_CA_BUNDLEwskazującą na Twój prywatny urząd certyfikacji lub konkretny pakiet certyfikatów. W linii poleceń możesz to zrobić w następujący sposób:

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

Jeśli masz swój urząd certyfikacji i nie chcesz wpisywać za exportkażdym razem, możesz dodać REQUESTS_CA_BUNDLEdo swojego ~/.bash_profilew następujący sposób:

echo "export REQUESTS_CA_BUNDLE=/path/to/your/certificate.pem" >> ~/.bash_profile ; source ~/.bash_profile
Mike N
źródło
Zmienna środowiskowa była tym, czego potrzebowałem, aby PyCharm działał z certyfikatami przechowywanymi w pliku certyfikatów OpenSSL.
Brady
Mam w łańcuchu certyfikat z podpisem własnym. To rozwiązanie rozwiązało mój problem z biblioteką boto3.
Ilkin,
7

Przypadek, w którym potrzeba wielu certyfikatów, został rozwiązany w następujący sposób: Połącz wiele głównych plików PEM, myCert-A-Root.pem i myCert-B-Root.pem, do pliku. Następnie ustaw żądania REQUESTS_CA_BUNDLE var na ten plik w moim ./.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
Halbert Stone
źródło
To był mój "ahhh" moment dnia ... Wielkie dzięki ... Dzięki tej podpowiedzi dostałem mój podpisany przez siebie certyfikat jira do pracy ... ;-) Wiem, że może być setki stron i odpowiedzi, które to opisują , ale znalazłem twoje, więc otrzymujesz moje uznanie za pomoc w rozwiązaniu mojego problemu ... d
alexrjs
4

Ustawienie export SSL_CERT_FILE=/path/file.crtpowinno wystarczyć.

gizzmole
źródło
Dzięki. U mnie działa (podczas gdy REQUESTS_CA_BUNDLEzmienna nie działa w moim przypadku).
Pascal H.
0

Jeśli ktoś przypadkiem wyląduje tutaj (tak jak ja), chcąc dodać CA (w moim przypadku Charles Proxy) dla httplib2, wygląda na to, że możesz dołączyć go do cacerts.txtpliku dołączonego do pakietu pythona.

Na przykład:

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

Zmienne środowiskowe, do których odwołują się inne rozwiązania, wydają się być specyficzne dla żądań i nie zostały odebrane przez httplib2 podczas moich testów.

Mat Schaffer
źródło