python ssl错误违反协议

use*_*867 2 python ssl https python-2.7

我正在尝试使用python登录并下载一些文件,使用代码:

import sys
import urllib
import urllib2
import httplib, ssl, socket
class HTTPSConnectionV3(httplib.HTTPSConnection):
    def __init__(self, *args, **kwargs):
        httplib.HTTPSConnection.__init__(self, *args, **kwargs)

    def connect(self):
        sock = socket.create_connection((self.host, self.port), self.timeout)
        if self._tunnel_host:
            self.sock = sock
            self._tunnel()
        try:
            self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_SSLv3)
        except ssl.SSLError, e:
            print("Trying SSLv3.")
            #self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_TLSv1)
            self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_SSLv23)

class HTTPSHandlerV3(urllib2.HTTPSHandler):
    def https_open(self, req):
        return self.do_open(HTTPSConnectionV3, req)
# install opener
urllib2.install_opener(urllib2.build_opener(HTTPSHandlerV3()))
if __name__ == "__main__":
    ##fill the login form
    query={}
    query['username']='USER'
    query['password']='007'
    query['submit']='Submit'
    if len(sys.argv) != 2:
                    print >> sys.stderr, "missing date"
                    sys.exit()
    #submit the form
    #http_req = urllib2.Request(url='https://www.connect2nse.com/iislNet', data=urllib.urlencode(query))
    http_req = urllib2.Request(url='https://www.connect2nse.com/iislNet/Login.jsp', data=urllib.urlencode(query))
    #http_req = urllib2.Request(url='https://www.connect2nse.com/iislNet/index.html', data=urllib.urlencode(query))
    webpage = urllib2.urlopen(http_req)
    webpage_headers = webpage.info()
    #extract the cookie
    cookie = webpage_headers['Set-Cookie'].split(';', 1)[0]
    print >> sys.stderr, "Set-Cookie:", cookie
    http_req = urllib2.Request(url='https://connect2nse.com/iislNet/MY.jsp', headers={'Cookie': cookie})
    webpage = urllib2.urlopen(http_req)
Run Code Online (Sandbox Code Playgroud)

我收到以下错误

Trying SSLv3.
Traceback (most recent call last):
  File "MYSCRIPT.py", line 51, in <module>
    webpage = urllib2.urlopen(http_req)
  File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 400, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 418, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
    result = func(*args)
  File "MYSCRIPT.py", line 27, in https_open
    return self.do_open(HTTPSConnectionV3, req)
  File "/usr/lib/python2.7/urllib2.py", line 1177, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [Errno 8] _ssl.c:504: EOF occurred in violation of protocol>
Run Code Online (Sandbox Code Playgroud)

虽然直到上个月这个工作正常,但现在却出现了上述错误

我已经尝试过这个链接,但无济于事.使用python中的请求我使用r = requests.get(' https://www.connect2nse.com/iislNet/Login.jsp',auth =('USER','007'))r.status_code 401但是我'我也不确定如何继续使用请求.尝试@Antti Haapala的解决方案对我不起作用,在2.7.3和6上尝试过

try: 
# self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_SSLv23) 
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_TLSv1) 
except ssl.SSLError, e: 
print("Trying SSLv3.",e) 
# self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=5) 
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_SSLv23)
Run Code Online (Sandbox Code Playgroud)

TLSv1和SSLv23都给出了类似的错误.

error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure' and
error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure'
Run Code Online (Sandbox Code Playgroud)

@JF Sebastian,谢谢,但我100%确定登录名和密码是正确的,因为我在chrome中使用时也一样.当我使用TLSv1_2时,我得到以下错误

 python MYSCRIPT.py 090315
Trying SSLv3.
Traceback (most recent call last):
  File "MYSCRIPT.py", line 51, in <module>
    webpage = urllib2.urlopen(http_req)
  File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 400, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 418, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
    result = func(*args)
  File "MYSCRIPT.py", line 27, in https_open
    return self.do_open(HTTPSConnectionV3, req)
  File "/usr/lib/python2.7/urllib2.py", line 1174, in do_open
    h.request(req.get_method(), req.get_selector(), req.data, headers)
  File "/usr/lib/python2.7/httplib.py", line 958, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python2.7/httplib.py", line 992, in _send_request
    self.endheaders(body)
  File "/usr/lib/python2.7/httplib.py", line 954, in endheaders
    self._send_output(message_body)
  File "/usr/lib/python2.7/httplib.py", line 814, in _send_output
    self.send(msg)
  File "/usr/lib/python2.7/httplib.py", line 776, in send
    self.connect()
  File "MYSCRIPT.py", line 22, in connect
    self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_TLSv1_2)
AttributeError: 'module' object has no attribute 'PROTOCOL_TLSv1_2'
Run Code Online (Sandbox Code Playgroud)

该网站发布了兼容浏览器设置的通知,之后脚本开始出现故障此链接显示兼容性,您需要点击新的SSL DOC

Ant*_*ala 5

您的代码强制连接始终使用SSL 3协议,SSL 3在过去的千年中已被TLSv1 取代.

在Pythons <2.7.9(2.7.8)中,您应该选择ssl.PROTOCOL_SSLv23,它将支持OpenSSL库支持的最高TLS数.它特别是在当前的OpenSSL版本意味着SSLv3,TLSv1,TLSv1.1,和TLSv1.2 支持.与标志不同,最近版本的OpenSSL 不接受SSLv2.

因此我们得到:

def connect(self):
    sock = socket.create_connection((self.host, self.port), self.timeout)
    if self._tunnel_host:
        self.sock = sock
        self._tunnel()

    self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
                                ssl_version=ssl.PROTOCOL_SSLv23)
Run Code Online (Sandbox Code Playgroud)

如果requests连接,那么您可能希望使用它.您的授权应作为表单值发送,并作为POST请求发送:

data = {}
data['username']='USER'
data['password']='007'
data['submit']='Submit'
r = requests.post("https://www.connect2nse.com/iislNet/Login.jsp", data=data)
Run Code Online (Sandbox Code Playgroud)

ssl.PROTOCOL_TLSv1_2 出现在Python 2.7.9和3.4中,但在该版本号之前也可以使用一些反向端口.

但是,如果PROTOCOL_TLSv1_2ssl模块,这也意味着,TLS 1.2仅不能在Python使用甚至与硬编码协议常数(5) -的原因是从相当明显_ssl源代码 -整数是唯一有意义的Python扩展模块,它用于选择实际的构造方法.


在Python 2.7.9中,将有一个SSLContext对象,可用于为SSL套接字创建设置标志 ; 在那里,至少可以尝试使用monkey_patch作为未来证明,但是对于没有TLSv1.2补丁的版本也是不可能的.

关于如何禁用SSL 2和3,TLSv1.0,TLSv1.1,TLSv1.2,强制使用假设的TLSv1.3(?)的 2.7.9示例代码:

ssl_sock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_SSLv23)
ssl_sock.context.options |= ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 \
   | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2
Run Code Online (Sandbox Code Playgroud)