如何在Python套接字中加密http请求

时间:2018-03-25 12:26:28

标签: python sockets ssl

import socket
import ssl

host = 'postlm.com'   #browsec addon v2.0.7     
port = 443               
def pp(a):
    s = socket.socket()        
    s = ssl.wrap_socket(s)  
    s.connect((host, port))
    s.send(a)
    aaa=b''
    for i in range(2):
        aa=s.recv(10240)
        if not aa:break
        print('='*100)
        if  b'Connection established' in aa:
            a=(a.replace(b'CONNECT ',b'GET https://'))
            s.send(a)
            continue
        aaa+=aa
        break
    s.close()
    return (aaa)

if __name__ == '__main__':
    j=b'CONNECT www.wikipedia.org:443 HTTP/1.1\r\nHost: www.wikipedia.org\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-GB,en;q=0.5\r\nProxy-Authorization: Basic NWE5MTMxODE5ZjY4NjNlOWJkMDAwYjdiOkdXbHVpTm9JejMzMTRvZXNFemI3emNLTXU2aHZrc214\r\nAccept-Encoding: gzip, deflate\r\nProxy-Connection: keep-alive\r\n\r\n'

    # j=b'GET http://example.com HTTP/1.1\r\nHost: example.com\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-GB,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive\r\n\r\n'
    a=pp(j)
    print(a)

输出:

b'HTTP/1.1 400 Bad Request\r\nServer: nginx/1.13.6\r\nDate: Sun, 25 Mar 2018 12:20:29 GMT\r\nContent-Type: text/html\r\nContent-Length: 271\r\nConnection: close\r\n\r\n<html>\r\n<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>\r\n<body bgcolor="white">\r\n<center><h1>400 Bad Request</h1></center>\r\n<center>The plain HTTP request was sent to HTTPS port</center>\r\n<hr><center>nginx/1.13.6</center>\r\n</body>\r\n</html>\r\n'
  

普通HTTP请求已发送到HTTPS端口

Browsec Uncompatible Addon 这是Addon的旧版本,带有这个插件我可以在整个系统中使用它,代理为localhost:49736

1 个答案:

答案 0 :(得分:1)

It is not fully clear for me what the intention if your code is since you've only dumped some code without documenting its function. But I've tried to extract from this kind what you are probably trying to do and where your problem is. Given the code I can see that you are doing the following:

  1. Connect to postlm.com port 443 with SSL.
  2. Send a CONNECT request over this SSL connection: This suggests that postlm.com:443 must be a HTTP proxy which gets accessed by HTTPS. This is not an invalid but still unusual setup. This CONNECT then builds a connection to www.wikipedia.org. Usually a CONNECT requires a port number but you don't give one. Probably 443 (https) is assumed in this case.
  3. After you've somehow read the response of this proxy to the request you check for success. The check is unusual in that you don't check for HTTP status code 200 but instead for some specific string. But maybe it works with this proxy.
  4. Then you send a GET https:// request over this connection. The expectation with CONNECT is that it only builds a tunnel and that any encrypted traffic (i.e. your https:// URL) should be done inside the tunnel. This would mean that you would need another encryption (to the target site) on top of your already established encryption (to the proxy) before you send the next HTTP request. But you don't do it and that's why it (wikipedia.org) complains that a plain HTTP request was send to a HTTPS socket.

I don't think that you can do this kind of double ssl wrapping with Python. Apart from that you should not put a https:// URL as the path in a HTTP (non-proxy) request but only the path on the server.