【HTTPS】双向认证 附demo

环境搭建

使用python3 来搭建demo, python相对c++ 实现功能很快。这里主要是讲下https 中 ssl/tls 的原理。 使用python 编写demo。

python3 安装需要的依赖

pip3 install flask

异常报错 timeout ,推荐使用
**pip --default-timeout=1688 install 库名称 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com ** 进行安装

证书生成

#!/bin/bash

PROJECT_NAME="https Project"

# Generate the openssl configuration files.
cat > ca_cert.conf << EOF
[ req ]
distinguished_name     = req_distinguished_name
prompt                 = no

[ req_distinguished_name ]
 O                      = $PROJECT_NAME Certificate Authority
EOF

cat > server_cert.conf << EOF
[ req ]
distinguished_name     = req_distinguished_name
prompt                 = no

[ req_distinguished_name ]
 O                      = $PROJECT_NAME
 CN                     = httpsServer
EOF

cat > client_cert.conf << EOF
[ req ]
distinguished_name     = req_distinguished_name
prompt                 = no

[ req_distinguished_name ]
 O                      = $PROJECT_NAME Device Certificate
 CN                     = httpsClient
EOF

mkdir ca
mkdir server
mkdir client

# 生成私钥
openssl genrsa -out ca.key 1024
openssl genrsa -out server.key 1024
openssl genrsa -out client.key 1024

# 根据私钥创建证书请求文件,需要输入一些证书的元信息:邮箱、域名等
openssl req -out ca.req -key ca.key -new -config ./ca_cert.conf
openssl req -out server.req -key server.key -new -config ./server_cert.conf
openssl req -out client.req -key client.key -new -config ./client_cert.conf

# 结合私钥和请求文件,创建自签署证书,  此处建议使用二级证书来生成服务端和客户端证书
openssl x509 -req -in ca.req -out ca.crt -sha1 -days 5000 -signkey ca.key
openssl x509 -req -in server.req -out server.crt -sha1 -CAcreateserial -days 5000 -CA ca.crt -CAkey ca.key
openssl x509 -req -in client.req -out client.crt -sha1 -CAcreateserial -days 5000 -CA ca.crt -CAkey ca.key

mv ca.crt ca.key ca/
mv server.crt server.key server/
mv client.crt client.key client/

# rm *.conf
# rm *.req
# rm *.srl

需要先安装 openssl . 然后执行上面的脚本。

https 客户端 直接上代码

# 单项验证服务端证书
import urllib.request
import ssl

if __name__ == '__main__':
    # 客户端认证服务端证书需要ca 此处单项认证服务端
    CA_FILE = "caCert/ca/ca.crt"
    # CA_FILE = "caCert/client/client.crt"
    context = ssl.SSLContext(ssl.PROTOCOL_TLS)
    context.check_hostname = False
    context.load_verify_locations(CA_FILE)
    context.verify_mode = ssl.CERT_REQUIRED
    try:
        request = urllib.request.Request('https://127.0.0.1:8091/login')
        res = urllib.request.urlopen(request, context=context)
        print(res.code)
        print(res.read().decode("utf-8"))
    except Exception as ex:
        print("Found Error in auth phase:%s" % str(ex))

使用根证书验证签发的服务端证书

服务端验证客户端

from flask import Flask

import ssl

app = Flask(__name__)

# @app.route('/login')
# def hello_world():
#     return 'Hello World!'

# if __name__ == '__main__':
#     app.run(host="0.0.0.0", port=8091, ssl_context=('caCert/server/server.crt', 'caCert/server/server.key'))
    
    
# 方法改造 增加ssl 证书校验
@app.route('/login')
def hello_world():
    return 'Hello World!'

# 配置ssl上下文,关键函数 
def get_ssl_context():
    # ca根证书
    ca_crt_path = 'caCert/ca/ca.crt'
    # 吊销列表
    server_crl_path = ''
    # 服务端证书和密钥
    server_crt_path = 'caCert/server/server.crt'
    server_key_path = 'caCert/server/server.key'
    # server_crt_path = 'caCert/ca/ca.crt'
    # server_key_path = 'caCert/ca/ca.key'
    
    # 创建ssl上下文
    ssl_context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLSv1_2)
    # 选择认证模式
    # ssl_context.verify_mode = ssl.CERT_REQUIRED
    ssl_context.verify_mode = ssl.CERT_NONE
    # 不校验域名
    ssl_context.check_hostname = False
    # 吊销证书校验,只检查对端,不检查中间CA
    # ssl_context.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF
    # ssl_context.load_verify_locations(server_crl_path)
    
    # 加密套件
    ssl_context.set_ciphers = ("HIGH:!SSLv3:!TLSv1:!aNULL:@STRINGTH")
    
    # 加载根证书
    ssl_context.load_verify_locations(ca_crt_path)
    # 加载服务端证书密钥,用于通信时使用
    ssl_context.load_cert_chain(certfile=server_crt_path, keyfile=server_key_path)
    
    return ssl_context



if __name__ == '__main__':
    ssl_context = get_ssl_context()
    app.run(host="0.0.0.0", port=8091, ssl_context=ssl_context)

细节可以参考:
https://www.cnblogs.com/Zzbj/p/15868210.html
https://blog.51cto.com/u_15127652/4590575

postman 验证测试

在这里插入图片描述
** 添加客户端证书**

完成:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值