65

私はUbuntu12.10をOpenSSL1.0.1c、python 2.7.3、Requests 1.0.3および1.0.4(両方を試しました)で使用しており、次のコードを使用してurl変数でWebサイトに接続しようとしています。

def SendInitialRequest(xmlmessage, redirecturl):
    url = 'https://centineltest.cardinalcommerce.com/maps/txns.asp'

    payload = 'cmpi_msg=' + ET.tostring(xmlmessage)
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
    }
    r = requests.post(url, data=payload, headers=headers, verify=None)
    print r.text

次のエラーがスローされます。

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "clams/libs/centinel/thinclient.py", line 134, in SendInitialRequest
    r = requests.post(url, data=payload, headers=headers, verify=None)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/api.py", line 87, in post
    return request('post', url, data=data, **kwargs)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/sessions.py", line 269, in request
    resp = self.send(prep, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/sessions.py", line 364, in send
    r = adapter.send(request, **kwargs)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/adapters.py", line 163, in send
    raise SSLError(e)
requests.exceptions.SSLError: [Errno 8] _ssl.c:504: EOF occurred in violation of protocol

opensslで接続しようとすると、次のようになります。

$ openssl s_client -connect centineltest.cardinalcommerce.com:443
CONNECTED(00000003)
140019346777760:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 226 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

tls1を使用するように強制すると、機能します(出力は切り捨てられます)。

$ openssl s_client -tls1 -connect centineltest.cardinalcommerce.com:443
CONNECTED(00000003)
depth=2 C = US, O = "thawte, Inc.", OU = Certification Services Division, OU
verify error:num=20:unable to get local issuer certificate
verify return:0
---

私はこれについて多くのバグレポートを見てきました。ただし、Pythonリクエストライブラリを使用して回避する方法は見つかりませんでした。どんな援助でも大歓迎です。

4

10 に答える 10

47

リクエストの発行ページから他の人のためにこれをここに再投稿します:

Requestsは、バージョン1より前のこれの実行をサポートしていません。バージョン1以降は、次のようにHTTPAdapterをサブクラス化する必要があります。

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
import ssl

class MyAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(num_pools=connections,
                                       maxsize=maxsize,
                                       block=block,
                                       ssl_version=ssl.PROTOCOL_TLSv1)

あなたがそれをしたとき、あなたはこれをすることができます:

import requests
s = requests.Session()
s.mount('https://', MyAdapter())

そのセッションオブジェクトを介したすべてのリクエストは、TLSv1を使用します。

于 2013-01-03T19:45:42.123 に答える
38

verify = Falseを設定すると、サーバー証明書の検証がスキップされるだけで、SSLプロトコルエラーの解決には役立ちません。

この問題は、WebサーバーでSSLv2が無効になっていることが原因である可能性がありますが、Python2.xはデフォルトでPROTOCOL_SSLv23との接続を確立しようとします。これはhttps://github.com/python/cpython/blob/360aa60b2a36f5f6e9e20325efd8d472f7559b1e/Lib/ssl.py#L1057で発生します

ssl_versionキーワードパラメータをオーバーライドすることにより、sslモジュールでssl.wrap_socket()にモンキーパッチを適用できます。次のコードはそのまま使用できます。リクエストを行う前に、これをプログラムの開始時に配置してください。

import ssl
from functools import wraps
def sslwrap(func):
    @wraps(func)
    def bar(*args, **kw):
        kw['ssl_version'] = ssl.PROTOCOL_TLSv1
        return func(*args, **kw)
    return bar

ssl.wrap_socket = sslwrap(ssl.wrap_socket)
于 2014-06-11T15:10:55.560 に答える
26

requests私のために解決するための「セキュリティ」パッケージエクストラをインストールする:

sudo apt-get install libffi-dev
sudo pip install -U requests[security]
于 2016-02-15T21:35:38.097 に答える
5

これは既知のバグです。ハックで回避できます。

開いてsite-packages/requests/packages/urllib3/connectionpool.py(または、自分のプロジェクト内でリクエストのローカルコピーを作成して)、次のようなブロックを変更します。

def connect(self):
    # Add certificate verification
    sock = socket.create_connection((self.host, self.port), self.timeout)

    # Wrap socket using verification with the root certs in
    # trusted_root_certs
    self.sock = ssl_wrap_socket(sock, self.key_file, self.cert_file,
                                cert_reqs=self.cert_reqs,
                                ca_certs=self.ca_certs,
                                server_hostname=self.host,
                                ssl_version=self.ssl_version)

に:

def connect(self):
    # Add certificate verification
    sock = socket.create_connection((self.host, self.port), self.timeout)

    # Wrap socket using verification with the root certs in
    # trusted_root_certs
    self.sock = ssl_wrap_socket(sock, self.key_file, self.cert_file,
                                cert_reqs=self.cert_reqs,
                                ca_certs=self.ca_certs,
                                server_hostname=self.host,
                                ssl_version=ssl.PROTOCOL_TLSv1)

それ以外の場合は、どこかにハッキーの少ないオーバーライドがあると思いますが、一目見ただけではオーバーライドが見つかりませんでした。

:補足としてrequests、MacOSのPIP(1.0.4)からは、指定したURLでのみ機能します。

于 2012-12-31T14:07:49.370 に答える
3

私は同じ問題を抱えていました:

SSLError(e)
を発生させますrequests.exceptions.SSLError:[Errno 8] _ssl.c:504:プロトコルに違反してEOFが発生しました

フィドラーを実行していましたが、フィドラーのキャプチャを停止しましたが、このエラーは表示されませんでした。フィドルのせいかもしれません。

于 2013-08-28T00:34:52.303 に答える
3

私はこのエラーに遭遇しました、そして修正はPython2.7がサポートしていないSNIをオフにしているようです:

http://bugs.python.org/issue5639

Python2.7のurllib3GoogleAppEngineのSNIエラー

于 2013-12-07T04:34:53.747 に答える
3

上記の修正が機能しない人へ。

それを修正するためにファイルssl.pyを変更する必要がありました。関数create_default_contextを探し、行を変更します。

context = SSLContext(PROTOCOL_SSLv23)

context = SSLContext(PROTOCOL_TLSv1)

多分誰かがssl.pyを編集せずにもっと簡単な解決策を作ることができますか?

于 2016-08-31T13:39:08.047 に答える
1

残念ながら、受け入れられた答えは私にはうまくいきませんでした。verify=False一時的な回避策として、安全なWebサイトに接続するときにも使用できます。

SSLErrorをスローするPythonリクエストから

requests.get('https://example.com', verify=True)
于 2013-03-06T11:00:09.090 に答える
1

私も同様の問題を抱えていましたが、単に無視すれば、ssl検証は私にとっては魅力的なものになると思います。したがって、httpsスキームを使用してサーバーに接続しますが、証明書を検証しないようにサーバーに指示します。

を使用しrequestsます。verify=False代わりに言及するNone

    requests.post(url, data=payload, headers=headers, verify=False)

これが必要な人のために働くことを願っています:)。

于 2017-06-27T07:36:43.580 に答える
0

TLSを介してRabbitMQMQTTサーバーに接続するときにこのエラーが発生しました。サーバーが壊れていることは確かですが、とにかくOpenSSL 1.0.1で動作しましたが、OpenSSL1.0.2では動作しませんでした。

これを使用して、Pythonでバージョンを確認できます。

import ssl
ssl.OPENSSL_VERSION

古いバージョンのPythonを使用する以外に、Python内でOpenSSLをダウングレードする方法がわかりません(少なくともWindowsでは静的にリンクされているようです)。

于 2016-04-13T15:27:17.787 に答える