双向SSL证书认证,也就是双向TLS(mTLS),要求客户端和服务器端都提供证书进行验证,确保双方的身份可信。这对于安全性要求高的API场景非常重要,比如银行或者内部系统之间的通信,下面说一下通用步骤和关键点:

1. 生成证书

1.1 创建根证书(CA)

bash

生成CA私钥

openssl genrsa -out ca.key 2048

生成自签名CA证书

openssl req -new -x509 -days 365 -key ca.key -out ca.crt

1.2 生成服务器证书

bash

生成服务器私钥

openssl genrsa -out server.key 2048

生成证书签名请求(CSR)

openssl req -new -key server.key -out server.csr

用CA证书签名服务器证书

openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt

1.3 生成客户端证书

bash

生成客户端私钥

openssl genrsa -out client.key 2048

生成客户端CSR

openssl req -new -key client.key -out client.csr

用CA证书签名客户端证书

openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt

2. 配置API网关

2.1 上传证书到API网关

将以下文件上传到网关(不同网关方式不同):

ca.crt(CA证书,用于验证客户端证书)

server.crt 和 server.key(服务器证书和私钥)

2.2 启用双向SSL认证

AWS API Gateway:

在API设置中启用“Mutual TLS Authentication”,上传ca.crt。

Kong API Gateway:

bash

创建服务并启用mTLS

curl -X POST http://localhost:8001/services \

data "name=my-service" \

data "url=https://backend.example.com" \

data "client_certificate.id=<CA_CERT_ID>"

Nginx:

nginx

server {

listen 443 ssl;

ssl_certificate server.crt;

ssl_certificate_key server.key;

ssl_client_certificate ca.crt;  # 客户端CA证书

ssl_verify_client on;           # 强制验证客户端证书

}

3. 客户端配置

客户端发起请求时需携带证书和私钥:

使用cURL测试

bash

curl --cert client.crt --key client.key --cacert ca.crt https://api.example.com

代码示例(Python)

python

import requests

response = requests.get(

"https://api.example.com",

cert=("client.crt", "client.key"),

verify="ca.crt"  # 信任的CA证书

)

print(response.text)

4. 常见问题排查

证书链不完整

确保服务器证书包含完整的证书链(例如合并server.crt和ca.crt)。

证书域名不匹配

检查证书的Subject Alternative Name (SAN)是否包含API网关的域名。

客户端未发送证书

确认客户端请求中正确附加了证书和私钥。

证书过期或无效

使用openssl x509 -in cert.crt -text -noout检查有效期和签名。

5. 注意事项

证书管理:定期轮换证书,避免使用过期证书。

性能影响:双向SSL会增加握手开销,建议启用会话复用(TLS Session Resumption)。

日志监控:在网关日志中检查TLS握手错误(如SSL_VERIFY_FAILED)。

用户通过以五个上步骤,为API网关和客户端将实现双向身份验证的SSL证书,确保通信双方的可信性。具体配置可能因网关类型(如Kong、AWS、Nginx等)略有差异,需参考官方文档调整。