Ошибка Httplib2 ssl

Сегодня я столкнулся с одной интересной проблемой.

Я использую рекомендованную четырьмя квадратами библиотеку python httplib2 raise

SSLHandshakeError(SSLError(1, '_ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed'),) 

при попытке запросить токен oauth

response, body = h.request(url, method, headers=headers, body=data)

в

_process_request_with_httplib2 function

Кто-нибудь знает, почему это происходит?

Ответ 1

Если вы знаете, что сайт, который вы пытаетесь получить, является "хорошим парнем", вы можете попробовать создать свой "открыватель" следующим образом:

import httplib2
if __name__ == "__main__":
    h = httplib2.Http(".cache", disable_ssl_certificate_validation=True)
    resp, content = h.request("https://site/whose/certificate/is/bad/", "GET")

(интересная часть disable_ssl_certificate_validation=True)

Из документов: http://bitworking.org/projects/httplib2/doc/html/libhttplib2.html#httplib2.Http

РЕДАКТИРОВАТЬ 01:

Поскольку ваш вопрос был на самом деле, почему это происходит, вы можете проверить this или this.

EDIT 02:

Увидев, как этот ответ был посещен большим количеством людей, чем я ожидал, я хотел бы немного объяснить, когда может быть полезно отключить проверку сертификата.

Во-первых, немного светлый фон о том, как работают эти сертификаты. В ссылках, приведенных выше, довольно много информации, но здесь все равно.

Сертификаты SSL должны быть проверены хорошо известным (по крайней мере, хорошо известным вашему браузеру) Центр сертификации. Обычно вы покупаете весь сертификат у одного из этих властей (Symantec, GoDaddy...)

В общем, идея такова: эти центры сертификации (CA) предоставляют вам сертификат, который также содержит информацию CA. У ваших браузеров есть список известных ЦС, поэтому, когда ваш браузер получит сертификат, он сделает что-то вроде: "HmmmMMMmmm.... [браузер делает здесь более суровое лицо]... я получил сертификат, и он говорит, что он проверен Symantec. Знаю ли я, что парень" Symantec"? [браузер переходит в список известных ЦС и проверяет Symantec] О, да! Хорошо, сертификат хороший!

Вы можете сами увидеть эту информацию, если вы нажмете на маленькую блокировку по URL-адресу в своем браузере:

Информация о сертификате Chrome

Однако есть случаи, когда вы просто хотите протестировать HTTPS, и создаете свой собственный центр сертификации с помощью пары командной строки и вы используете этот "настраиваемый" ЦС для подписания "настраиваемого" сертификата, который вы только что создали, не так ли? В этом случае ваш браузер (который, кстати, в вопросе httplib2.Http) не будет иметь ваш "пользовательский" ЦС среди списка доверенных ЦС, поэтому он скажет, что сертификат недействителен. Информация по-прежнему собирается зашифровать, но то, что браузер говорит вам, заключается в том, что она не полностью доверяет тому, что вы путешествуете в зашифрованном виде в том месте, где вы предполагаете, что это произойдет.

Например, предположим, что вы создали набор пользовательских ключей и центров сертификации и всех mambo-jumbo, следующих этот учебник для вашего localhost FQDN и что ваш файл сертификата CA находится в текущем каталоге. У вас вполне может быть сервер, работающий на https://localhost:4443, используя ваши собственные сертификаты и многое другое. Теперь ваш файл сертификата CA находится в текущем каталоге, в файле ./ca.crt (в том же каталоге, в котором будет запущен ваш Python script). Вы можете использовать httplib2 следующим образом:

h = httplib2.Http(ca_certs='./ca.crt')
response, body = h.request('https://localhost:4443')
print(response)
print(body)

... и вы больше не увидите предупреждения. Зачем? Поскольку вы сказали httplib2, чтобы посмотреть сертификат CA на ./ca.crt)

Однако, поскольку Chrome (для указания браузера) не знает об этом сертификате CA, он считает это недействительным:

введите описание изображения здесь

Кроме того, срок действия сертификатов истекает. Там есть шанс, что вы работаете в компании, которая использует внутренний сайт с SSL-шифрованием. Он работает нормально в течение года, а затем ваш браузер начинает жаловаться. Вы идете к человеку, который отвечает за безопасность, и спрашивайте: "Эй, я здесь предупреждаю! Что происходит?" И ответ вполне может быть "О, мальчик! Я забыл продлить сертификат! Все в порядке, просто принимай это сейчас, пока я не исправим это". (правда, хотя в ответе были короткие слова, я получил : - D)

Ответ 2

В последних версиях httplib2 используется собственный хранилище сертификатов.

# Default CA certificates file bundled with httplib2.
CA_CERTS = os.path.join(
     os.path.dirname(os.path.abspath(__file__ )), "cacerts.txt")

Если вы используете ubuntu/debian, вы можете явно передать путь к файлу сертификата системы, например

httplib2.HTTPSConnectionWithTimeout(HOST, ca_certs="/etc/ssl/certs/ca-certificates.crt")

Ответ 3

Может быть, это может быть так: У меня возникла та же проблема, и при отладке Google Lib я обнаружил, что причина в том, что я использовал более старую версию httplib2 (0.9.2). Когда я обновился до последней версии (0.14.0), это сработало.

Если вы уже установили самую последнюю версию, убедитесь, что какая-то библиотека не устанавливает более старую версию httplib2 в своих зависимостях.