gpt4 book ai didi

rest - 如何让客户端接受服务器的SSL证书

转载 作者:太空宇宙 更新时间:2023-11-03 13:32:59 24 4
gpt4 key购买 nike

我正在尝试从客户端对服务器进行 REST 调用。

服务器端

我正在使用 Flask 作为网络服务器。我使用以下命令生成了证书 (cert.pem) 和公钥 (key.pem)。

openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365

服务器端代码如下。

from flask import Flask
from flask_restful import Resource, Api

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

class HelloWorld(Resource):
def get(self):
return {'hello': 'world'}

@app.route('/someroute/<arg1>,<arg2>', methods=['GET'])
def fn1(arg1,arg2):
res = fn2(arg1, arg2)
return str(res)

def fn2(un,pwd):
#Do something and return a number
return num

if __name__ == '__main__':
context = ('cert.pem', 'key.pem')
app.run(host="ip", port=port1, debug=True, ssl_context=context)

客户端

我有一个 Flask 应用程序,我需要从中对上述服务器进行 REST 调用。以下是我用来执行此操作的代码。

import requests
# Below is the part of a function which gets called upon hitting a route in Flask.
ret = requests.get("https://<ip>:<port1>/<someroute>/arg1,arg2", verify=True)
print ret.text

这会抛出以下错误。

requests.exceptions.SSLError: [Errno 1] _ssl.c:510: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

此错误是预期的,因为客户端不知道该证书。如果我跳过证书验证 (verify=False),一切都运行良好。

如何让客户端信任这个未知的服务器 SSL 证书?我已经看到需要在客户端使用 Nginx 的解决方案。我们不能对 flask (客户端)本身做一些改变以使其信任我的服务器吗?如果是,我应该在 Flask 中做出什么确切的改变?此外,建议 urllib 是否优于 requests

更新 1

我这里还有一个问题。从上面,我了解到 requests.get 每次我们进行 REST 调用时都会验证证书(如果我错了请纠正我)。但是,这看起来像是一个额外的负担。难道不能一开始就建立一个加密连接,用私钥加密交换数据吗?那么,如何实现开始部分 - 通过使用公钥加密私钥发送到服务器,然后通过使用私钥加密数据开始交换数据。

最佳答案

OC (original comment):

Server Side

I am using Flask as web server. I have generated the certificate(cert.pem) and public key(key.pem) using the following command.

openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 36

如果你阅读 man req 它说,

-out filename
This specifies the output filename to write to or standard output by default.

-keyout filename
This gives the filename to write the newly created private key to. If this option is not specified then the filename present in the configuration file is used.

在这里,cert.pem 可以称为公共(public)证书,而 key.pem 实际上是您的私钥(保持安全和私密)。傅立叶。


OC (original comment):

This error is expected as the certificate is not known to the client. Everything is working perfectly fine if I skip the certificate verification (verify=False).

How do I make the client trust this unknown server SSL certificate? I have seen solutions where I need to use Nginx on the client side. Can we not do some changes on flask(client side) itself to make it trust my server? If yes, what is that exact change I should be making in Flask? Also, suggest if urllib is better than requests.

我会倒过来回答这个问题,但首先要了解一些背景知识。我发现这些链接对于理解 SSL/TLS 握手如何发生以及身份验证如何进行非常有用 - 在高层次上

现在,回到你的问题,

  • requests > urllib(个人观点,但是requests确实有很好的支持并且很成熟——并不意味着urllib 不是)

  • 您似乎想仅进行服务器身份验证,因为您的客户端需要服务器的公共(public)证书。来自 How SSL and TLS provide authentication :

The certificates required are as follows, where CA X issues the certificate to the SSL or TLS client, and CA Y issues the certificate to the SSL or TLS server:

For server authentication only, the SSL or TLS server needs:

  • The personal certificate issued to the server by CA Y

  • The server's private key

and the SSL or TLS client needs:

  • The CA certificate for CA Y

You can pass verify the path to a CA_BUNDLE file or directory with certificates of trusted CAs:

requests.get('https://github.com', verify='/path/to/certfile')

一旦您这样做并获得了良好的证书,它就应该可以工作。

注意:OC 中的 openssl 命令不显示 key /证书对的任何主题,这仍然会导致证书验证失败,请参阅说明如何执行的文档生成自签名证书。有提供 SAN (SubjectAltNames) 的要求,因此仅在主题中提供 CommonName (CN) 不会在未来证明您的过程。

编辑:IBM 文档中关于 CA 的说法可能令人困惑,但由于这是一个自签名证书,您不必担心这一点,只需将其视为您的 Flask 服务器就是 SSL/TLS 服务器,而任何客户端该服务器可以使用服务器的公钥进行服务器验证。


OC (original comment):

From above, I understood that requests.get verifies the certificate every time we make a REST call (Please correct me if I am wrong). But, this looks like an extra load.

没错。每次都会进行验证。为避免这种情况,您可以使用 requests SSL Cert Verification 中提到的 requests.Session()


OC (original comment):

Can we not have an encrypted connected established in the beginning and exchange the data by encrypting it with a private key? So, how to implement the beginning part - Send private key by encrypting it with the public key to the server and then start exchanging data by encrypting the data with the private key.

这在列出的 IBM 文档中有很好的解释

关于rest - 如何让客户端接受服务器的SSL证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49008440/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com