• python使用https


    post请求举例:
        httpsConn = None    
        try:    
            httpsConn = httplib.HTTPSConnection(host)
            sock = socket.create_connection((httpsConn.host, httpsConn.port))
            try:
                httpsConn.sock = ssl.wrap_socket(sock, ca_certs=CERT_FILE, cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_SSLv3)
                #self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_SSLv3)
            except ssl.SSLError, e:
                print("Trying SSLv3.")
                try:
                    httpsConn.sock = ssl.wrap_socket(sock, ca_certs=CERT_FILE, cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_SSLv23)
                    #self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_SSLv23)
                except ssl.SSLError, e:
                    print("Trying SSLv23.")
                    try:
                        httpsConn.sock = ssl.wrap_socket(sock, ca_certs=CERT_FILE, cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_TLSv1)
                    except ssl.SSLError, e:
                        print("Trying TLSv1.")
                        try:
                            httpsConn.sock = ssl.wrap_socket(sock, ca_certs=CERT_FILE, cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_SSLv2)
                        except ssl.SSLError, e:
                            print("Trying SSLv2.")        
            
            httpsConn.request("POST", path, body, headers)
            res = httpsConn.getresponse()
            headers = {}
            for k, v in res.getheaders():
                headers[k] = v
            return res.status, headers, res.read()
        except Exception, e:
            import traceback
            print traceback.format_exc()
            return e
        finally:
            if httpsConn:
                httpsConn.close
    备注:
    如果只有服务器端有私钥,客户端有公钥,则客户端的程序需要指定公钥文件,见代码:httpsConn.sock = ssl.wrap_socket(sock, ca_certs=CERT_FILE, cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_SSLv3),是通过ca_certs参数指定的,CERT_FILE是文件的路径,保证能够找到即可;如果是是一个文件夹下有多个文件,然后这多个文件都是需要用到的,比如A域名的证书和B域名的证书,A服务器在对接口处理请求的时候,会向B端发请求,如此客户端需要将A域名证书和B域名证书都添加进来,所以只要把文件夹路径设置成ca_certs参数的值即可。
    另外,如果不确定SSL的版本,则需要尝试多个不同的SSL版本:ssl.PROTOCOL_TLSv1、ssl_version=ssl.PROTOCOL_SSLv2、ssl_version=ssl.PROTOCOL_SSLv23、ssl_version=ssl.PROTOCOL_SSLv3。
    get请求的话,就将httpsConn.request("POST", path, body, headers)中的"POST"换成"GET"就好了,然后body设置为None即可。
     
    以下是服务器端代码:
    from socket import socket, AF_INET, SOCK_STREAM
    import ssl
    
    KEYFILE = 'server_key.pem'   # Private key of the server
    CERTFILE = 'server_cert.pem' # Server certificate (given to client)
    
    def echo_client(s):
        while True:
            data = s.recv(8192)
            if data == b'':
                break
            s.send(data)
        s.close()
        print('Connection closed')
    
    def echo_server(address):
        s = socket(AF_INET, SOCK_STREAM)
        s.bind(address)
        s.listen(1)
    
        # Wrap with an SSL layer requiring client certs
        s_ssl = ssl.wrap_socket(s,
                                keyfile=KEYFILE,
                                certfile=CERTFILE,
                                server_side=True
                                )
        # Wait for connections
        while True:
            try:
                c,a = s_ssl.accept()
                print('Got connection', c, a)
                echo_client(c)
            except Exception as e:
                print('{}: {}'.format(e.__class__.__name__, e))
    
    echo_server(('', 20000))
    之后是客户端连接服务器端的例子:
    >>> from socket import socket, AF_INET, SOCK_STREAM
    >>> import ssl
    >>> s = socket(AF_INET, SOCK_STREAM)
    >>> s_ssl = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED, ca_certs = 'server_cert.pem')
    >>> s_ssl.connect(('localhost', 20000))
    >>> s_ssl.send(b'Hello World?')
    12
    >>>s_ssl.recv(8192)
    b'Hello World?'
    >>>
     
    备注:其中 ssl.wrap_socket(s,cert_reqs=ssl.CERT_REQUIRED,ca_certs = 'server_cert.pem') 的ca_certs就是需要在客户端指定的证书,这个是服务器给的公钥证书。
    证书的格式:一般有der格式、pem格式,且格式不能单纯通过后缀名去进行判定,比如一个后缀名是crt,就认为其不是pem的格式是错误的。

  • 相关阅读:
    Linux部署web项目
    bash: mysql: command not found(解决方法)
    mysql登录遇到ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
    mysqld:未被识别的服务(解决方法)
    Xshell4连接,Linux系统中文显示乱码解决办法
    F5双机冗余配置
    H3C S10512虚拟化配置
    cisco3900板卡sm-es3g-24-p使用方法
    详解Cisco ACS AAA认证-1(转)
    cisco路由器license的相关命令简单梳理(转)
  • 原文地址:https://www.cnblogs.com/absoluteli/p/13959760.html
Copyright © 2020-2023  润新知