双向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等)略有差异,需参考官方文档调整。