如何使用客户端上的“requests”模块和服务器上的“flask-restful”验证 https 请求的自签名证书(TLS1.2)

Posted

技术标签:

【中文标题】如何使用客户端上的“requests”模块和服务器上的“flask-restful”验证 https 请求的自签名证书(TLS1.2)【英文标题】:How to verify self signed certificate for https requests using the "requests" module on the client and "flask-restful" on the server (TLS1.2) 【发布时间】:2022-01-02 05:40:08 【问题描述】:

这是我目前所拥有的。使用 openssl,我现在有这些文件: ca.crt、ca.key、c​​a.srl、server.crt、server.csr、server.key。

我遵循了这个教程: https://carolinafernandez.github.io/development/2017/09/13/HTTPS-and-trust-chain-in-Flask

现在将它作为服务器:

from flask import Flask, request
from flask_restful import Resource, Api, reqparse
import psycopg2
import ssl
import sys

app = Flask(__name__)
api = Api(app)

# TODO: https security
HTTPS_ENABLED = True
VERIFY_USER = True

API_HOST = "0.0.0.0"
API_PORT = 8000
API_CRT = "server.crt"
API_KEY = "server.key"
API_CA_T = "ca.crt"

context = None
if(HTTPS_ENABLED):
    context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
    
    if(VERIFY_USER):
        context.verify_mode = ssl.CERT_REQUIRED
        context.load_verify_locations(API_CA_T)

    try:
        context.load_cert_chain(API_CRT, API_KEY)
    except Exception as e:
        sys.exit("Error starting server: ".format(e))

...[implementation of api]...

if __name__ == '__main__':
    app.run(ssl_context=context, host=API_HOST, port=API_PORT, debug=True)

在客户端机器上,我有这段代码。我还将 ca.crt 复制到那台机器上:

import os
import requests
import ssl

def test():
    response = requests.get("https://[url of server]:8000/helloworld", verify='ca.crt')
    #response = requests.get("http://[url of server]:8000/helloworld")
    print(response.text);

def print_version():
    print(ssl.OPENSSL_VERSION)

if __name__ == "__main__":
    test()
    #print_version()

在启动服务器 api 然后运行客户端代码后,我在客户端收到此错误消息:

requests.exceptions.SSLError: HTTPSConnectionPool(host='[url of server]', port=8000): Max retries exceeded with url: /helloworld (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1123)')))

这样做的目的是让我可以进行安全的服务器到服务器通信。在可预见的未来,它实际上将是一台服务器向另一台服务器发送 https 请求。我是否使用了错误的文件格式来验证客户必须使用的任何内容?无论如何,我都不是 TLS 方面的专家,所以我真的不知道所有文件扩展名之间的区别(例如,我见过一个 .pem 文件用于验证)。

在我之前展示的链接中,我还尝试了生成 client.pem 并在验证字段中使用它的路线。

【问题讨论】:

【参考方案1】:

根据下面的错误,[url of server] 需要像实际的host + port 例如127.0.0.1:8000

requests.exceptions.SSLError: HTTPSConnectionPool(host='[url of server]', port=8000): Max retries exceeded with url: /helloworld (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1123)')))

【讨论】:

以上是关于如何使用客户端上的“requests”模块和服务器上的“flask-restful”验证 https 请求的自签名证书(TLS1.2)的主要内容,如果未能解决你的问题,请参考以下文章

Requests 与 BeautifulSoup 模块

requests

使用requests模块保存网络上的图片

python笔记8:requests模块

爬虫学习 06.Python网络爬虫之requests模块

使用 python-requests 模块更新 Session 中的 Cookie