我正在尝试使用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)
我收到以下错误
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>
尽管到上个月为止一切正常,但现在却出现上述错误
我已经尝试过This link,但无济于事。
在我使用的python中使用请求
r = request.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)
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'
@ J.F。 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'
该站点发布了兼容浏览器设置的通知,此后脚本开始出现故障this link shows compatibility, you need to click on NEW SSL DOC
python大神给出的解决方案
您的代码强制连接始终使用SSL 3协议,在最近的千年中,TLSv1取代了SSL 3。
在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)
如果连接了requests
,则可能要使用它。您的授权应作为表单值和POST request发送:
data = {}
data['username']='USER'
data['password']='007'
data['submit']='Submit'
r = requests.post("https://www.connect2nse.com/iislNet/Login.jsp", data=data)
ssl.PROTOCOL_TLSv1_2
出现在Python 2.7.9和3.4中,但即使在该版本号之前,也可以使用某些反向移植。
但是,如果PROTOCOL_TLSv1_2
不在ssl
模块中,则这也意味着TLS 1.2仅在具有硬编码协议常量(5)的情况下不能在Python中使用-reason is quite obvious from the _ssl
source code-整数仅对Python扩展有意义模块,用于选择实际的构造方法。
在Python 2.7.9中,将有一个SSLContext对象,可用于set flags on for SSL socket creation;在那里至少可以尝试使用monkey_patch作为将来的证明,但是对于没有TLSv1.2补丁的版本则不可能。
关于如何禁用SSL 2和3,TLSv1.0,TLSv1.1,TLSv1.2的2.7.9示例代码,强制使用假设的TLSv1.3(?):
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