在 mTLS 场景下,如何为每款移动 APP 签发独立客户端证书?

解读

面试官想知道你是否能把“CouchDB 的 mTLS 机制”与“国内移动 App 的证书生命周期管理”打通。
核心考点有三层:

  1. 证书信任链如何落地到 CouchDB 的 verify_funcacert_file 配置;
  2. 每款 App 的证书如何做到“一机一证”且可吊销,符合国密合规与工信部备案要求;
  3. 自动化流程怎样与 DevSecOps 结合,避免发版当天人工拷证书。

知识点

  • CouchDB 14.x 的 [ssl] port、cert_file、key_file、cacert_file、verify_fun 五元组配置
  • verify_fun = {fun, [verify_peer, {fail_if_no_peer_cert, true}]} 强制双向认证
  • 国内 CA 体系:公共 CA(如 CFCA、上海 CA) vs 企业自建 私有 CA(需过国密局《电子认证服务许可证》年检)
  • X.509 v3 关键扩展:SubjectAltName 放 App BundleID、OID 1.3.6.1.4.1.XX 放渠道号,方便 CouchDB 侧做 细粒度授权
  • 短周期证书(≤90 天)+ OCSP stapling 降低吊销延迟;CouchDB 需开启 partial_chain 支持中间级轮转
  • 移动侧安全存储:Android Keystore / iOS SecureEnclave 私钥不可导出,配合 证书指纹绑定 防止二次打包
  • 自动化:使用 SPIFFE/SPIRE企业 PKI 的 CMP/EST 协议 做证书下发,CouchDB 通过 sidecar 容器 热加载 CRL

答案

  1. 自建 国密双证书体系(SM2 签名+加密),在 私有 CA 里为每款 App 创建独立 中间 CA;中间 CA 的 CommonName 即 App 包名,便于审计。
  2. 利用 EST 协议企业 CMP 网关,在 App 首次启动时生成 设备级密钥对(SM2 256 位),私钥存 TEE,公钥带设备 ID、渠道号、用户 ID 作为 CSR 扩展,提交到 CA。
  3. CA 返回 短周期(7 天)证书,同时把证书序列号写入 CouchDB 的 _users 库 的 _id 字段,实现“证书即账号”。
  4. CouchDB 配置:
    [ssl]
    port = 6984
    cert_file = /opt/couchdb/cert/server.pem
    key_file  = /opt/couchdb/cert/server.key
    cacert_file = /opt/couchdb/cert/ca-chain.pem
    verify_fun = {couch_httpd_ssl, verify_fun, [{fail_if_no_peer_cert, true}]}
    
    verify_fun 回调里,先校验 OCSP 状态,再比对 _users 库是否存在该序列号,实现 实时吊销
  5. 发布流水线:GitLab CI 调用 cfssl-sm 签发证书,把 crl.pem 推送到对象存储;CouchDB 通过 inotify 热加载 crl.pem,零停机。
  6. 合规:私有 CA 每年通过 国密局年检,证书算法标识使用 1.2.156.10197.1.501,满足《GB/T 38636-2020》要求;同时向 工信部备案 App 证书策略

拓展思考

  • 如果 App 需要 离线运行 30 天,可把证书有效期拉长到 35 天,并在 App 内置 CRL 快照OCSP 缓存,同步时通过 _revs_diff 接口把吊销列表增量拉回,保证 离线优先 场景的安全性。
  • 当 CouchDB 集群跨 两地三中心,可在每个中心部署 只读 CA 节点,用 Raft 同步 CRL,避免中心 CA 单点成为 同步瓶颈
  • 未来若接入 零信任网关,可把 CouchDB 的 证书序列号 作为 SPIFFE ID 的一部分,由 OPA/Istio 统一授权,实现 数据库层服务网格层 的证书复用,降低运维复杂度。