美文网首页程序员python趣味100例
Python网络编程笔记(五):TLS和SSL

Python网络编程笔记(五):TLS和SSL

作者: 郝开心信札 | 来源:发表于2018-08-02 09:41 被阅读437次

    传输层安全协议(TLS),前身是安全套接层SSL

    TLS无法保护的信息

    能保护的信息包括:
    与请求URL之间的HTTPS连接及其返回内容、密码、cookies等可能在套接字双向传递的信息。

    无法保护的信息:

    • 本机和远程主机的地址
    • 端口号
    • DNS查询
    • 数据块的大致大小

    一个典型的TLS交换场景

    • 客户端向服务器索取证书--表示身份的电子文件。
    • 客户端和服务器共同信任的某个机构应该对证书进行签名,证书必须包含一个公钥。
    • 服务器需要证明其确实拥有公钥对应的私钥。
    • 客户端对证书中声明的身份进行验证,确认是否与想连接的主机名一致。
    • 客户端和服务器对**加密算法、压缩、以及密钥这些设定进行协商。
    • 开始传输。

    完美前向安全(PFS,Perfact Forward Security)

    如果有人在未来获取或者破解了我们的私钥,那么他们能否捕捉到以前的TLS对话,并将他们保存,以便在未来进行解密。

    何时使用

    很多程序员不在自己的程序中支持TLS,而选择交给第三方工具,比如nginx、Apache等。

    python如何使用

    标准库的ssl内置支持OpenSSL,最好使用Python 3.4之后的版本。

    编写模式:

    • 创建一个“上下文”对象(create_default_context())
    • 打开连接
    • 调用上下文对象的wrap_socket()方法, 表示TLS接管后续连接。

    show me the code

    #!/usr/bin/env python3
    # Foundations of Python Network Programming, Third Edition
    # https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter06/safe_tls.py
    # Simple TLS client and server using safe configuration defaults
    
    import argparse, socket, ssl
    
    def client(host, port, cafile=None):
        purpose = ssl.Purpose.SERVER_AUTH
        context = ssl.create_default_context(purpose, cafile=cafile)
    
        raw_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        raw_sock.connect((host, port))
        print('Connected to host {!r} and port {}'.format(host, port))
        ssl_sock = context.wrap_socket(raw_sock, server_hostname=host)
    
        while True:
            data = ssl_sock.recv(1024)
            if not data:
                break
            print(repr(data))
    
    def server(host, port, certfile, cafile=None):
        purpose = ssl.Purpose.CLIENT_AUTH
        context = ssl.create_default_context(purpose, cafile=cafile)
        context.load_cert_chain(certfile)
    
        listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        listener.bind((host, port))
        listener.listen(1)
        print('Listening at interface {!r} and port {}'.format(host, port))
        raw_sock, address = listener.accept()
        print('Connection from host {!r} and port {}'.format(*address))
        ssl_sock = context.wrap_socket(raw_sock, server_side=True)
    
        ssl_sock.sendall('Simple is better than complex.'.encode('ascii'))
        ssl_sock.close()
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser(description='Safe TLS client and server')
        parser.add_argument('host', help='hostname or IP address')
        parser.add_argument('port', type=int, help='TCP port number')
        parser.add_argument('-a', metavar='cafile', default=None,
                            help='authority: path to CA certificate PEM file')
        parser.add_argument('-s', metavar='certfile', default=None,
                            help='run as server: path to server PEM file')
        args = parser.parse_args()
        if args.s:
            server(args.host, args.port, args.s, args.a)
        else:
            client(args.host, args.port, args.a)
    

    更多参考:让SSL/TLS协议流行起来:深度解读SSL/TLS实现

    相关文章

      网友评论

        本文标题:Python网络编程笔记(五):TLS和SSL

        本文链接:https://www.haomeiwen.com/subject/yycjvftx.html