Learning
VOL. VII · NO. 104 · OTC Derivatives · 19 JUL 2026

Cert App Digital Certificate

OTC 衍生品 · 19 JUL 2026 · 6 min read · 1,215 words
· · ·

ODTS-54: Cert App 数字证书与电子签章——合同签署的安全基础

目标读者:想理解 ODTS 合同签署中数字证书如何工作、签章流程、证书生命周期的 BA/PM

相关文档:ODTS-47 (安全架构), ODTS-17 (交易确认), ODTS-31 (合同运营)

为什么 BA/PM 需要理解数字证书

数字证书是衍生品合同签署的”最后一公里”——它把系统里的交易数据变成具有法律效力的文件。这个环节出故障,前面的所有流程都白费。

数字签名失败的真实代价:

  • 签署延迟 = 确认书逾期: 交易确认书 (confirmation) 通常要求在 T+1 内签署。如果 Cert App 签名流程卡住(证书过期、短信验证码系统故障、CA 机构响应超时),运营无法完成签署。根据 ISDA 协议,确认书逾期未签 = 交易在法律上未确认。如果一笔交易在 T+2 才完成签署,而标的在这两天内下跌了 3%,客户可以主张”交易未确认,我不承担此亏损”。 对于 5000 万名义本金的交易,3% = 150 万的潜在争议敞口。
  • 证书过期批量故障: 企业证书通常有效期 3-5 年,到期前需向 CA 机构续期。如果运营忘记提前续期,某个交易台的企业证书过期——所有合同签署中断。某券商曾发生过因证书过期,整个交易台半天无法签署合同。运营紧急联系 CA 机构加急续期(加急费 5000-10000 元),但半天内约 30 份确认书积压,其中 5 份逾期到了 T+2,客户投诉。
  • 运营维护成本: 一个中型券商每年需要管理 3-5 张企业证书 + 10-20 张个人证书。每张证书的申请、安装、续期、吊销操作平均消耗运营 1-2 小时。每年证书管理总耗时约 30-50 小时——这不是开发工作,是运营必须用 Excel 跟踪的”隐形事务”。
  • 短信验证码瓶颈: 签署流程中短信验证码失败(手机号错误、运营商网关故障),运营无法签署。替代方案:运营需要去合规部做线下身份核实,平均耗时 2-4 小时。 如果交易员需要紧急签署一笔当天起息的交易,这 2-4 小时的延迟意味着交易起息日推迟一天。

概述

Cert App 是 ODTS 的数字证书与电子签章服务,处理合同签署全流程——从短信验证、证书获取、数据签名到签章归档。其核心设计原则是 私钥不出服务器:签名操作在客户端(浏览器/USB Key)完成,Cert App 仅提供待签名数据和验证签名结果。

签署全流程

标准签署流程

运营打开合同 → 点击"签署"

  ▼ 第1步: 短信验证
  GET /cert/sendSMS?usage=sign&mobile=138****0000
  ← 验证码已发送(6位数字)

  ▼ 第2步: 用户输入验证码,系统验证

  ▼ 第3步: 获取待签名数据
  GET /cert/getDataToSign?contractId=SNB202507001&companyId=1001
  ← DataToSign JSON

  ▼ 第4步: 前端/本地调用证书私钥签名 dataToSign
  │  (使用系统证书或 USB Key)

  ▼ 第5步: 提交签名结果
  POST /cert/sign (signedData)

  ▼ 第6步: Cert App 验证签名
  │  用 certSn 对应的公钥验证 dataToSign 签名

  ▼ 第7步: 签署完成,合同归档
  │  合同 PDF 存至 HCP
  │  签署记录写入数据库


  Contract.confirmationStatus = SENT

DataToSign 数据结构

待签名数据是 Cert App 返回的 JSON 对象:

{
  "signatureId": "SIG20250716001",
  "dataToSign": "base64编码的合同摘要哈希",
  "certSn": "12:34:56:78:9A:BC:DE:F0",
  "digestAlg": "SHA-256",
  "signingTime": "2025-07-16T10:30:00+08:00"
}
字段说明
signatureId本次签署唯一标识
dataToSign合同文件的摘要哈希(Base64),待数字签名
certSn证书序列号,指定签署使用哪张数字证书
digestAlg摘要算法(SHA-256)
signingTime签名时间戳

安全关键: dataToSign 是合同 PDF 的 SHA-256 摘要,而非全文。这意味着:

  1. Cert App 不需要持有合同全文即可完成签署
  2. 签名验证等价于对整份合同的背书——任何合同修改都会导致摘要不同
  3. dataToSign 无法反推出合同内容

短信验证 API

签署前强制 SMS 验证,防止未授权操作:

GET /cert/sendSMS?usage=sign&mobile=13800138000&companyId=1001

响应:
{
  "code": "0",
  "message": "验证码已发送",
  "data": {
    "smsId": "SMS20250716001",
    "expireIn": 300
  }
}
  • 验证码有效期: 5 分钟
  • 验证码使用一次后失效
  • usage 参数区分: sign(签署), certManage(证书管理)

证书管理 API

Cert App 提供完整的数字证书生命周期管理:

端点方法用途
/userCertManager/getOneUserInfoGET查询单条证书申请记录
/userCertManager/searchUserInfoPOST分页搜索证书申请
/userCertManager/searchContractInfoPOST分页搜索签署合同记录
/userCertManager/deleteOneUserInfoPOST删除证书申请
/userCertManager/importUserInfoPOST导入证书申请(含附件上传)

证书申请导入字段:

POST /userCertManager/importUserInfo 请求体:

{
  "userId": "operator01",
  "companyId": 1001,
  "contractType": "ISDA",
  "certType": "CORPORATE",
  "certData": "base64编码的证书文件",
  "attachmentUrl": "/hcp/cert/import/snb2025070001.pfx"
}

证书类型

类型用途颁发有效期限
企业证书 (CORPORATE)公司级合同签署CA 机构(如 CFCA)3-5 年
个人证书 (PERSONAL)个人操作员签署企业内部 CA1-3 年
设备证书 (DEVICE)系统间身份认证内部1 年

签署记录查询

POST /userCertManager/searchContractInfo 分页查询签署历史:

{
  "companyId": 1001,
  "contractId": "SNB202507001",
  "pageNum": 1,
  "pageSize": 20
}

响应:
{
  "code": "0",
  "data": [{
    "contractId": "SNB202507001",
    "signatureId": "SIG20250716001",
    "signingTime": "2025-07-16T10:30:00+08:00",
    "certSn": "12:34:56:78:9A:BC:DE:F0",
    "signerId": "operator01",
    "status": "SIGNED"
  }]
}

法律合规

Cert App 的数字签名满足以下法规要求:

  1. 《中华人民共和国电子签名法》第十三条:使用数字证书的签名被视为可靠的电子签名,与手写签名或盖章具有同等法律效力
  2. 抗抵赖性 (Non-repudiation)signingTime + signedData 可举证签署人、签署时间和签署内容
  3. 签名验证:任何第三方可以用证书公钥验证 dataToSign 的签名是否有效

关键代码目录

eds-web-app/src/.../cert/
├── CertAppClient.java                ← HTTP REST 客户端封装
├── DataToSign.java                   ← 待签名数据 VO
├── SignResult.java                   ← 签名结果 VO
└── UserCertManagerClient.java        ← 证书管理客户端

odyssey/.../cert/
├── CertService.java                  ← Odyssey 侧签署服务
└── CertConfig.java                   ← Cert App 连接配置