web-dev-qa-db-ja.com

pycurlとSSL証明書

安全なサイト(HTTPS)にアクセスするためのpycurlスクリプトを記述しようとしています。

c = pycurl.Curl()
c.setopt(pycurl.USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0) Gecko/20100101 Firefox/8.0')
c.setopt(pycurl.URL, 'https://for-example-securedsite')
c.setopt(pycurl.COOKIEFILE, 'cookie.txt')
c.setopt(pycurl.COOKIEJAR, 'cookies.txt')
c.setopt(pycurl.WRITEDATA, file("page.html","wb"))   

以下のエラーが出ます。

pycurl.error:(60、 'SSL証明書の問題、CA証明書に問題がないことを確認してください。詳細:\ nerror:14090086:SSLルーチン:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed')

SSL証明書の取得に失敗したため、コードは失敗しました。

コードに以下の行を追加すると、エラーはなくなりました。

c.setopt(pycurl.SSL_VERIFYPEER, 0)   
c.setopt(pycurl.SSL_VERIFYHOST, 0)

上記のコードは、証明書の検証をスキップします。しかし、「中間者攻撃」を受けます。

ローカル証明書ストアにSSL証明書があることを知っています。誰でも私の証明書をエクスポートして私のコードを使用する方法を知っていますか。いくつかのサンプルコードはすばらしいでしょう。

御時間ありがとうございます!

26
K2M

そのとおりです。特に 最新のSSLの脆弱性 に照らして、その方法では中間者攻撃を受けます。次のように解決できます。

import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, "https://your-secure-website.com/")
curl.setopt(pycurl.SSL_VERIFYPEER, 1)
curl.setopt(pycurl.SSL_VERIFYHOST, 2)
curl.setopt(pycurl.CAINFO, "/path/to/updated-certificate-chain.crt")
curl.perform()

curlにはデフォルトで古い証明書リストが付属しています。更新する場合でも、テスト用に独自の証明書を使用する場合でも、更新された証明書チェーン.crtファイルをアクセス可能な場所に配置し、pycurl.CAINFOオプションを使用してそれを指定するようにしてください。

また、pycurl.SSL_VERIFYHOSTが最も高いセキュリティチェック設定である2に設定されていることを確認してください。

24
Suman

CURLのドキュメントを読みましたか SSL証明書について ?これはあなたの質問に直接対処しているようです...特に、項目2:

 2. Get a CA certificate that can verify the remote server and use the proper
    option to point out this CA cert for verification when connecting. For
    libcurl hackers: curl_easy_setopt(curl, CURLOPT_CAPATH, capath);

PycurlモジュールにはCAPATHオプションが含まれているようですので、コードに実装するのは簡単です。

1
larsks