使用 curl 和 TLS 1.2 双向调用 api 以及 public 个实体证书

Call api with curl and TLS 1.2 Two Way with public certificates of entities

我目前正在调用一项需要与 curl 和 ubuntu 相互验证的服务,目前 我有以下证书 certRoot.cercertSub.cerdomain.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

这个调用本身是正确的returns以下信息:

*   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 端验证调用的那一刻,它表明证书未发送并拒绝连接,我想这就是它 returns 错误的原因403(禁止)。

我也尝试通过直接传递证书来做到这一点,但是 returns 这个错误:

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()

希望以后对你有所帮助,对我来说,在找到解决方案之前,这是一项漫长的任务。