zoukankan      html  css  js  c++  java
  • 自签SSL证书实现客户端登录认证

    0.介绍

    自己开发的使用了SSL协议的软件,通常没必要从证书签发机构那里来获取证书,自签证书成了必要的选择。自签证书还可以用来实现客户端登录认证。

    1.创建CA

    创建CA的私钥
    openssl genrsa -des3 -out rootCA.key 4096
    创建CA的自签证书
    openssl req -x509 -new -nodes -sha256 -days 3650 -key rootCA.key -out rootCA.crt

    2.签发证书

    生成证书的私钥
    openssl genrsa -out server.key  4096
    生成待签名的文件
    openssl req -new -key server.key -out server.csr
    使用CA进行签名
    openssl x509 -req -CA rootCA.crt -CAKey  rootCA.key -CAcreateserial -days 365 -sha256 -in server.csr  -out server.crt

    这样就获取了经CA签发的私钥server.key和证书server.crt

    3.客户端的登录认证

    使用相同的CA来签发服务器证书和客户端证书,服务器就可以根据CA证书来鉴定客户端的是否具有登录权限。

    即:凡是经过CA签发的证书,都能登录成功;否则失败  。

    豌豆资源搜索网站https://55wd.com 广州vi设计公司http://www.maiqicn.com

    4.Python代码示例,演示如何验证客户端的证书

    服务端代码:

    import socket
    from socket import AF_INET, SOCK_STREAM, SO_REUSEADDR, SOL_SOCKET, SHUT_RDWR
    import ssl
    
    listen_addr = '127.0.0.1'
    listen_port = 8082
    server_cert = 'server.crt'
    server_key = 'server.key'
    ca_cert = 'rootCA.crt'
    
    context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH, cafile=ca_cert)
    context.verify_mode = ssl.CERT_REQUIRED
    context.load_cert_chain(certfile=server_cert, keyfile=server_key)
    # context.load_verify_locations(cafile=ca_cert)
    
    bindsocket = socket.socket()
    bindsocket.bind((listen_addr, listen_port))
    bindsocket.listen(5)
    
    while True:
        print("Waiting for client")
        newsocket, fromaddr = bindsocket.accept()
        print("Client connected: {}:{}".format(fromaddr[0], fromaddr[1]))
        conn = context.wrap_socket(newsocket, server_side=True)
        print("SSL established. Peer: {}".format(conn.getpeercert()))
        buf = b''  # Buffer to hold received client data
        try:
            while True:
                data = conn.recv(4096)
                if data:
                    # Client sent us data. Append to buffer
                    buf += data
                else:
                    # No more data from client. Show buffer and close connection.
                    print("Received:", buf)
                    break
        finally:
            print("Closing connection")
            conn.shutdown(socket.SHUT_RDWR)
            conn.close()

    客户端代码

    import socket
    import ssl
    
    host_addr = '127.0.0.1'
    host_port = 8082
    server_sni_hostname = 'example.com'
    ca_cert = 'rootCA.crt'
    client_cert = 'client.crt'
    client_key = 'client.key'
    
    context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=ca_cert)
    context.check_hostname = False
    context.load_cert_chain(certfile=client_cert, keyfile=client_key)
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    conn = context.wrap_socket(s, server_side=False, server_hostname=server_sni_hostname)
    conn.connect((host_addr, host_port))
    print("SSL established. Peer: {}".format(conn.getpeercert()))
    print("Sending: 'Hello, world!")
    conn.send(b"Hello, world!")
    print("Closing connection")
    conn.close()
  • 相关阅读:
    C++ FFLIB之FFXML: 极简化TinyXml 读取
    使用ffpython嵌入和扩展python
    Json 备忘录
    一位软件工程师的6年工作总结
    Sql Server 备忘录
    走出软件作坊
    asp.net 使用Jquery 调用WebService返回JSON 类型数据
    .NET 页面间传值的几种方法
    CKeditor安全使用
    新浪短信Web Service
  • 原文地址:https://www.cnblogs.com/qianxiaox/p/13730314.html
Copyright © 2011-2022 走看看