Httplib2 ssl错误

use*_*339 10 python httplib2 foursquare

今天我遇到了一个有趣的问题.

我正在使用foursquare推荐的python库httplib2 raise

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

在尝试请求oauth令牌时

response, body = h.request(url, method, headers=headers, body=data)
Run Code Online (Sandbox Code Playgroud)

_process_request_with_httplib2 function
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么会这样?

Bor*_*jaX 21

如果您知道您想要获得的网站是"好人",您可以尝试创建这样的"开场白":

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")
Run Code Online (Sandbox Code Playgroud)

(有趣的部分是disable_ssl_certificate_validation=True)

来自文档:http: //bitworking.org/projects/httplib2/doc/html/libhttplib2.html#httplib2.Http

编辑01:

由于您的问题实际上是为什么会发生这种情况,您可以检查这个这个.

编辑02:

看到更多人访问这个答案的方式比我想象的要多,我想解释一下,禁用证书验证可能有用时.

首先,介绍一下这些证书的工作原理.上面提供的链接中有相当多的信息,但无论如何它都在这里.

SSL证书需要由众所周知的(至少是您的浏览器熟知的)证书颁发机构进行验证.您通常从其中一个机构购买整个证书(Symantec,GoDaddy ...)

从广义上讲,这个想法是:那些证书颁发机构(CA)为您提供一个证书,其中还包含CA信息.您的浏览器有一个众所周知的CA列表,因此当您的浏览器收到证书时,它会执行以下操作:"HmmmMMMmmm .... [浏览器在这里做了一个多余的面孔] ...我收到了证书,它说它是由赛门铁克验证的.我知道"赛门铁克"的人吗? [浏览器然后进入其着名的CA列表并检查赛门铁克] 哦,是的!我这样做.好的,证书很好!

如果您通过浏览器中的URL点击小锁,您可以自己查看该信息:

Chrome证书信息

但是,在某些情况下,您只想测试HTTPS,并使用几个命令行工具创建自己的证书颁发机构,并使用该"自定义"CA签署您刚刚生成的"自定义"证书, 对?在这种情况下,您的浏览器(顺便提一下,在问题中httplib2.Http)不会在受信任的CA列表中包含您的"自定义"CA,因此它会说证书无效.这些信息仍然会加密传输,但是浏览器告诉你的是,它并不完全信任加密到你认为正在进行的地方.

例如,假设您在本教程中为您的localhost FQDN创建了一组自定义密钥和CA以及所有mambo-jumbo ,并且您的CA证书文件位于当前目录中.您可以https://localhost:4443使用自定义证书和诸如此类的服务器运行服务器.现在,您的CA证书文件位于当前目录中的文件中./ca.crt(将在您的Python脚本运行的同一目录中).你可以httplib2像这样使用:

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

......你再也看不到警告了.为什么?因为你被告知httplib2去寻找CA的证书./ca.crt)

但是,由于Chrome(引用浏览器)不知道此CA的证书,因此它会认为它无效:

在此输入图像描述

此外,证书到期.您有可能在使用SSL加密的内部站点的公司工作.它可以运行一年,然后您的浏览器开始抱怨.你去找负责保安的人,并问"哟!!我在这里得到这个警告!发生了什么事?" 答案很可能就是"哦,小伙子!!我忘了更新证书!没关系,从现在开始接受它,直到我解决它." (真实的故事,虽然我收到的答案中有脏话:-D)

  • 这真的不是一个好主意 - 你应该弄清楚你的验证失败的原因.通过禁用验证,您实际上删除了检测许多中间人攻击的能力,其中有人想冒充上游Foursquare服务器 - 即使是他们拥有的简单情况,您也无法检测到生成了自签名证书. (3认同)

Jay*_*mar 12

最新版本的httplib2默认为其自己的证书存储区.

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

如果你使用的是ubuntu/debian,你可以显式地将路径传递给系统证书文件

httplib2.HTTPSConnectionWithTimeout(HOST, ca_certs="/etc/ssl/certs/ca-certificates.crt")
Run Code Online (Sandbox Code Playgroud)