rest - 使用 curl 和 TLS 1.2 两种方式调用 api,使用实体的公共(public)证书

标签 rest ubuntu curl ssl-certificate mutual-authentication

我目前正在调用一项需要使用 curl 和 ubuntu 进行相互身份验证的服务,目前
我有以下证书certRoot.cer , certSub.cer , domain.com.cerpubkey.pem , 将证书添加到路径 /etc/ssl/certs/ca-certificates.crt将它们全部转换为 pem 格式,我调用了电话:

curl -v \
--key /etc/ssl/certs/ca-certificates.crt \
-u "user:password" \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{"info":"data"}' \
https://endpoint.com:4445/api/path
此调用本身是正确的,并返回以下信息:
*   Trying ip...
* Connected to endpoint.com (ip) port 4445 (#0)
* found 136 certificates in /etc/ssl/certs/ca-certificates.crt
* found 536 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_256_GCM_SHA384
*        server certificate verification OK
*        server certificate status verification SKIPPED
*        common name: endpoint.com (matched)
*        server certificate expiration date OK
*        server certificate activation date OK
*        certificate public key: RSA
*        certificate version: #3
*        subject: C=CO,ST=STATE,L=DATA,O=DATA,OU=Sistemas,CN=endpoint.com
*        start date: Tue, 03 Sep 2019 14:42:57 GMT
*        expire date: Thu, 02 Sep 2021 14:42:57 GMT
*        issuer: C=CO,ST=DATA,L=DATA,L=ADDRESS,O=DATA,OU=Gerencia de Sistemas,CN=DATA Sub CA Terceros
*        compression: NULL
* ALPN, server did not agree to a protocol
* Server auth using Basic with user 'user'
> POST api/path HTTP/1.1
> Host: endpoint.com:4445
> Authorization: Basic dXNycHJ1X2Jpb2NyZWRpdDpQc123YmExMjM7
> User-Agent: curl/7.47.0
> Accept: application/json
> Content-Type: application/json
> Content-Length: 920
> 
* upload completely sent off: 920 out of 920 bytes
< HTTP/1.1 403 Forbidden
< Date: Tue, 06 Apr 2021 21:37:21 GMT
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< Content-Security-Policy: frame-ancestors 'none'
< Content-Length: 234
< Content-Type: text/html; charset=iso-8859-1
< 
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /api/path
on this server.</p>
</body></html>
* Connection #0 to host endpoint.com left intact

但是在从api端验证调用的那一刻,它表明证书没有发送并拒绝连接,我想这就是它返回错误403(禁止)的原因。
我也尝试通过直接传递证书来做到这一点,但它返回此错误:
curl -v \
--key pubkey.pem \
--cert domain.com.cer \
-u "user:password" \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{"info":"data"}' \
https://endpoint.com:4445/api/path
在这种情况下,答案如下:
*   Trying ip...
* Connected to domain.com (ip) port 4445 (#0)
* found 136 certificates in /etc/ssl/certs/ca-certificates.crt
* found 536 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* error reading X.509 key or certificate file: Error in parsing.
* Closing connection 0
curl: (35) error reading X.509 key or certificate file: Error in parsing.

我澄清所有这一切也是通过 vpn 发生的,并且与这个 vpn 的连接已经正常,如果有人知道我如何解决这个问题,我非常感谢你,它可以使用任何语言或终端客户端。

最佳答案

为了成功完成这个调用,我使用 python 完成了它,然后我留下了我使用的代码:

import socket
import ssl
 
host_addr = 'domain.com'
host_port = 4445
server_sni_hostname = 'domain.com'
server_cert = '../DESTINATION.cer' #CERTIFICATE OF DESTINATION, IN PEM FORMAT ( -----BEGIN CERTIFICATE----- ...... -----END CERTIFICATE----- )
client_cert = '../CUSTOMER_CERTIFICATE.cer' #CUSTOMER CERTIFICATE, IN PEM FORMAT ( -----BEGIN CERTIFICATE----- ...... -----END CERTIFICATE----- )
client_key = '../CUSTOMER_PRIVATE_KEY.key' #CUSTOMER PRIVATE KEY, IN PEM AND PKCS8 FORMAT (-----BEGIN PRIVATE KEY----- ....... -----END PRIVATE KEY-----)
 
basicAuthHeader = 'dXNlcjpwYXNzd29yZA==' #USER:PASSWORD >> BASE64
 
method = 'POST /path/of/service HTTP/1.1\r\n'
headers = 'Host:'+host_addr+'\r\nContent-Type:application/json\r\nAuthorization:'+basicAuthHeader+'\r\nAccept:application/json\r\n\r\n'
body = '{"data":"string","data1":"string","data2":"string","data3":"string","data4":"string"}'
 
 
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=server_cert)
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. ")
print("Sending:")
conn.send(bytes(method+headers+body, 'utf-8'))
 
print("Receiving")
received = conn.recv(36000)
print(received)
 
 
print("Closing connection")
conn.close()
我希望它对您将来有所帮助,对我来说,在我找到解决方案之前,这是一项漫长的任务。

关于rest - 使用 curl 和 TLS 1.2 两种方式调用 api,使用实体的公共(public)证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66979612/

相关文章:

node.js - 带有 Angular 资源和服务器 Nodejs 的嵌套端点

regex - 查找接口(interface)的网关

PHP cURL 在本地工作,在 AWS 服务器上出现错误 77

java - 尝试使用 HttpClient 设置 session cookie

Django Tastypie 通过 PostMan REST 客户端与 API 交互

.net - 制作 Silverlight 和常规 .NET REST 客户端的最便携方式是什么

javascript - 使用 .json 扩展名强制从 Express.js 端点输出 JSON

android - adb 从 virtualbox ubuntu 推送到 android 设备非常慢

python - 带有 python 2 的 Ubuntu

php_curl 无法运行 https (Google+ API)