客户端证书 (mTLS)
客户端证书是 foren.dev 签发的 X.509 证书,让合作伙伴用 mTLS(双向 TLS) 认证调用 foren.dev API。比 API Token 更安全,适合高安全场景。
什么是 mTLS?
普通 HTTPS 是单向 TLS:客户端验证服务器身份。
mTLS 是双向:客户端除了验证服务器,还把自己的证书出示给服务器,服务器验证客户端身份。
客户端 foren.dev
│ │
│ ┌─────────────────────┐ │
│ │ 1. ClientHello │ │
│ │ 2. Client Cert │ ──────▶ │
│ │ 3. CertVerify │ │
│ └─────────────────────┘ │
│ │
│ ◀───── 4. Server Cert ──────────│
│ │
│ ┌─ 5. 双方验证完毕 ─┐ │
│ │ 6. Encrypted data │ ────────▶ │
│ └───────────────────┘ │
为什么用 mTLS 而不是 Bearer Token?
| 维度 | Bearer Token | mTLS 客户端证书 |
|---|---|---|
| --- | --- | --- |
| 凭证可复制 | ✅ 可以复制粘贴 | ❌ 私钥难复制(受密码保护) |
| 凭证泄露 | 撤销即可 | 需要吊销证书 |
| 每次请求自动签名 | ❌ 手动加 header | ✅ TLS 层自动 |
| 双向认证 | 单向 | 双向 |
| 性能开销 | 极低 | 中(TLS handshake) |
适合场景:高安全要求、自动化集成、Service-to-Service。
怎么签发
仅管理员可签发:后台登录 → 侧边栏 Certs → + Generate Certificate:
- Owner Name(必填):CN,例如 "Zhang San - Lab Foo"
- Associated License(可选):把证书关联到一个 license
- Valid Days:默认 365
生成后显示:
- 证书 PEM —— 立即显示,可复制
- 私钥下载 URL —— 一次性 URL,30 分钟内有效,私钥访问仅一次
⚠️ 私钥不会再次显示。请立即下载并妥善保管。
怎么下载私钥
生成后 30 分钟内访问私钥下载 URL:
curl "https://foren.dev/license/api/coforen/certs/download-key/?token=<token>"
返回:
{
"ok": true,
"key_pem": "-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----",
"format": "PEM"
}
30 分钟后过期,第一次成功后立即失效(单次使用)。
使用示例
curl (CLI 测试)
curl --cert client.crt --key client.key \
https://foren.dev/license/api/coforen/stats/
Python (requests)
import requests
response = requests.get(
'https://foren.dev/license/api/coforen/stats/',
cert=('/path/to/client.crt', '/path/to/client.key')
)
Nginx (作为客户端)
server {
listen 443 ssl;
server_name partner.example.com;
ssl_certificate /etc/ssl/foren_dev.crt;
ssl_certificate_key /etc/ssl/foren_dev.key;
# Use client cert for upstream connection
location /api/foren/ {
proxy_pass https://foren.dev/license/api/coforen/;
proxy_ssl_certificate /etc/ssl/client.crt;
proxy_ssl_certificate_key /etc/ssl/client.key;
}
}
吊销
管理员可在 Certs 列表点击 Revoke。吊销后:
- 该证书立即失效
- 加入 CRL(Certificate Revocation List)
- 任何 mTLS 请求都会被拒绝
CRL(证书吊销列表)
公开端点:GET /license/api/coforen/certs/crl/
{
"ok": true,
"crl": [
{
"serial": "abc123def456...",
"revoked_at": "2026-09-15T10:00:00Z",
"reason": "requested"
}
],
"generated_at": "2026-09-29T12:00:00Z",
"total": 5
}
客户端在 TLS handshake 时可查询 CRL 来检查证书是否被吊销。
验证证书
POST /license/api/coforen/certs/validate/
curl -X POST https://foren.dev/license/api/coforen/certs/validate/ \
-H 'Content-Type: application/json' \
-d '{"cert_pem": "-----BEGIN CERTIFICATE-----\n..."}'
返回:
{
"ok": true,
"valid": true,
"serial": "abc123...",
"subject": ["CN=Zhang San - Lab Foo", "O=ForenDev"],
"issuer": ["O=ForenDev"],
"not_before": "2026-09-29T12:00:00Z",
"not_after": "2027-09-29T12:00:00Z"
}
安全提示
- 私钥绝不提交到代码仓库
- 私钥文件权限
chmod 600 - 私钥存储:使用硬件安全模块(HSM)或密钥管理服务
- 私钥轮换:建议每年签发新证书
- 撤销后立即从所有系统中移除
下一步
- API 参考 · certs — 完整端点
- API 参考 · certs/crl — CRL 端点
- Admin 文档 · Certs