[flask]使用mTLS双向加密认证http通信

简介: [flask]使用mTLS双向加密认证http通信

前言

mTLS,全称为双向TLS(Mutual Transport Layer Security),是一种安全通信协议,确保通信双方在传输层进行身份验证。与单向HTTPS不同,吗TLS不仅要求客户端验证服务端的身份,还要求服务端验证客户端的身份。

PS:本文实验环境为OpenSSL 3.0.11 + Python 3.11 + Flask 3.0.2,自测python 3.8 + openssl 1.1会有问题。

生成证书

常见的证书生成方式就是自签名证书,有条件的话还是自建CA机构或者购买专门的证书。

  1. 生成ca根证书。生成过程中会提示填写密码,记住密码,后续会用到。这里直接声明Common Name为qw.er.com,可根据实际需求修改ON、OU、CN等信息。
openssl req -x509 -newkey rsa:4096 -keyout ca.key -out ca.crt -subj "/CN=qw.er.com"  -days 3650
  1. 新建并编辑openssl.cnf文件,根据实际需求修改CN、CN等信息
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
prompt = no
[req_distinguished_name]
countryName = CN
stateOrProvinceName = Anhui
localityName = Hefei
organizationName = zhangsan
commonName = qw.er.com
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = qw.er.com
  1. 创建服务端证书。生成私钥文件时会提示输入根证书密码。
openssl req -newkey rsa:2048 -nodes -keyout server.key -out server.csr -subj "/CN=qw.er.com" -config openssl.cnf
openssl x509 -req -in server.csr -out server.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -extensions v3_req -extfile openssl.cnf
  1. 创建客户端证书。生成私钥文件时会提示输入根证书密码
openssl req -newkey rsa:2048 -nodes -keyout client.key -out client.csr -subj "/CN=qw.er.com" -config openssl.cnf
openssl x509 -req -in client.csr -out client.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -extensions v3_req -extfile openssl.cnf

服务端示例

除了flask本身,只需要导入标准库ssl。注意证书路径需要是绝对路径。

from flask import Flask
import ssl
app = Flask(__name__)
@app.get("/health")
def health():
    return "ok"
def get_ssl_context():
    ca_crt_path = "/home/atlas/workspace/flask-learn/certs/ca.crt"
    server_crt = "/home/atlas/workspace/flask-learn/certs/server.crt"
    server_key = "/home/atlas/workspace/flask-learn/certs/server.key"
    password = "qwerasdf"
    context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_SERVER)
    context.verify_mode = ssl.CERT_REQUIRED
    context.load_verify_locations(ca_crt_path)
    context.load_cert_chain(certfile=server_crt, keyfile=server_key, password=password)
    return context
if __name__ == "__main__":
    ssl_context = get_ssl_context()
    app.run(host="0.0.0.0", port=5000, ssl_context=ssl_context)

客户端示例

  • 方式1:使用curl命令
curl -k --cacert ca.crt --key client.key --cert client.crt https://127.0.0.1:5000/health
  • 方式2:使用requests库。注意修改hosts文件将qw.er.com映射到IP
import requests
ca_crt_path = "/home/atlas/workspace/flask-learn/certs/ca.crt"
client_crt = "/home/atlas/workspace/flask-learn/certs/client.crt"
client_key = "/home/atlas/workspace/flask-learn/certs/client.key"
url = "https://qw.er.com:5000/health"
resp = requests.get(url, cert=(client_crt, client_key), verify=ca_crt_path)
print(resp.status_code)
print(resp.text)
  • 方式3:使用httpx库。注意修改hosts文件将qw.er.com映射到IP
import httpx
import ssl
def get_ssl_context():
    password = "qwerasdf"
    ca_crt_path = "/home/atlas/workspace/flask-learn/certs/ca.crt"
    client_crt = "/home/atlas/workspace/flask-learn/certs/client.crt"
    client_key = "/home/atlas/workspace/flask-learn/certs/client.key"
    context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT)
    context.verify_mode = ssl.CERT_REQUIRED
    context.load_verify_locations(ca_crt_path)
    context.load_cert_chain(certfile=client_crt, keyfile=client_key, password=password)
    return context
url = "https://qw.er.com:5000/health"
context = get_ssl_context()
with httpx.Client(verify=context) as client:
    resp = client.get(url)
    print(resp.status_code)
    print(resp.text)
相关文章
|
6月前
|
Cloud Native 算法 区块链
站在巨人的肩膀上:gRPC通过HTTP/2构建云原生时代的通信标准
gRPC是云原生时代高效通信标准,基于HTTP/2实现,支持四种服务方法。通过.proto文件定义接口,生成多语言Stub,实现跨语言调用。其请求响应结构清晰,结合Headers、Data帧与Trailers,保障高性能与可扩展性,广泛应用于微服务架构中。
318 0
|
6月前
|
安全 算法 网络安全
SSL/TLS协议如何确保HTTP通信的安全
通过这些机制和过程,SSL/TLS对HTTP通信提供了强大的保护,确保数据不被未授权的第三方访问或篡改,这对维护数据隐私和网络安全至关重要。随着互联网技术的不断进步,SSL/TLS协议本身也在不断更新和升级,以对抗新出现的威胁和满足现代网络的要求。
364 10
|
算法 数据库 数据安全/隐私保护
摘要认证,使用HttpClient实现HTTP digest authentication
这篇文章提供了使用HttpClient实现HTTP摘要认证(digest authentication)的详细步骤和示例代码。
1204 2
HTTP 报文解构:深入剖析 HTTP 通信的核心要素
【10月更文挑战第21天】随着网络技术的不断发展和演进,HTTP 报文的形式和功能也可能会发生变化,但对其基本解构的理解始终是掌握 HTTP 通信的关键所在。无论是在传统的 Web 应用中,还是在新兴的网络技术领域,对 HTTP 报文的深入认识都将为我们带来更多的机遇和挑战。
|
存储 安全 Java
shiro学习二:shiro的加密认证详解,加盐与不加盐两个版本。
这篇文章详细介绍了Apache Shiro安全框架中密码的加密认证机制,包括不加盐和加盐两种加密方式的实现和测试。
932 0
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
468 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
|
存储 NoSQL Java
|
Linux Python
【Azure 应用服务】Azure App Service For Linux 上实现 Python Flask Web Socket 项目 Http/Https
【Azure 应用服务】Azure App Service For Linux 上实现 Python Flask Web Socket 项目 Http/Https
308 0
|
云安全 安全 数据建模
《数字证书:互联网世界的"身份证"与"防盗门"》 ——揭秘网络安全背后的加密江湖
在2023年某深夜,上海陆家嘴金融公司机房遭遇黑客攻击,神秘青铜大门与九大掌门封印的玉牌突现,阻止了入侵。此门象征数字证书,保障网络安全。数字证书如验钞机识别假币,保护用户数据。它通过SSL/TLS加密、CA认证和非对称加密,构建安全通信。证书分为DV、OV、EV三类,分别适合不同场景。忽视证书安全可能导致巨额损失。阿里云提供一站式证书服务,助力企业部署SSL证书,迎接未来量子计算和物联网挑战。
|
安全 算法 网络协议
【网络原理】——图解HTTPS如何加密(通俗简单易懂)
HTTPS加密过程,明文,密文,密钥,对称加密,非对称加密,公钥和私钥,证书加密