Skip to content

云签电子签名认证证书完整调用时序 ​

本页面面向外部调用方(签署平台),按阶段展示个人/机构、SM2/RSA 云签电子签名认证证书从身份审核、申请、签发、托管,到签名(逐次确认 / 预授权)与凭据管理的完整调用顺序。各节文字只写主干与陷阱,正常流向见各节时序图。

一、身份预审时序 ​

身份预审为前置阶段,与证书签发解耦:终端用户在平台发起身份审核,经创建审核链接取得 access_url 渲染到平台页面,由用户在审核页完成身份审核、证书签发意愿确认、私钥托管意愿确认(开启审核链接预授权时,还会同时确认签名授权次数、有效期、协议与可选 PIN)。

  1. 调用创建审核链接(POST /openapi/v3/audit-links;可选 prefill_data.preauthorization),取得 access_url 渲染到平台页面;
  2. 终端用户在审核页完成身份审核与各项意愿确认;
  3. 调用获取审核链接详情轮询至审核通过,保存 person_info.id 或 organization.id(审核拒绝或链接过期则终止)。通过后可紧接下单,也可延后另行下单。

二、申请证书签发时序 ​

申请入口是创建订单,签发为异步过程(CertCloud 内部完成 CSR 获取、CA 签发与云签托管,全程无需平台参与)。路径中的 {productId} 是产品 ID,返回的 data.id 才是后续查询使用的 orderId;issued 只表示 CA 已签发,仅证书 status=NORMAL 才表示材料已在云签就绪。

  1. 通过创建订单(POST /openapi/v3/orders/{productId})下单:certificate.csr_from 必须传 esign,certificate.key_algo 选 SM2 或 RSA;响应 data.id 即 orderId;
  2. 通过获取订单详情轮询至 issued 或 failed;
  3. 通过查询证书映射轮询取得 certId,并保存 subjectId、managerId(未就绪时可能为空,继续轮询);
  4. 通过查询证书状态轮询至 NORMAL——继续轮询的条件只有一条:status === "PENDING_ISSUE" 且未返回 hostingFailed,其余一切取值(含 hostingFailed: true、VOIDED 与未知值)一律停轮,详见停轮公式。

各类证书的调用序列完全一致,差异仅在下单请求体,见下方各类型下单请求体差异。

审核链接预授权签发 ​

审核链接开启预授权时,可改用同步签发证书创建订单:请求只需引用审核链接返回的个人或组织 ID,并提供稳定的 alternative_order_id 与 esign_sign_task_id;组织订单无需再次提交联系人。CertCloud 在订单持久化前同步执行云签预授权 CSR 流程(A1.1),获得 CSR 和 esign_sign_grant_token。

esign_sign_grant_token 可随 HTTP 200 或 HTTP 202 返回,只通过创建响应交付:签署平台必须立即按敏感凭据保存并交付给后续签名调用;普通订单详情不返回该 Token。若响应丢失,必须用相同备用订单 ID、签署任务 ID 和原始业务参数重试同步创建接口。

各类型下单请求体差异 ​

下列四类对应创建订单文档中的示例,调用序列同上,仅下单请求体不同。每类均有基础级 / 高等级两档产品,档位只决定 {productId}(审核强度由产品在云签侧确定),调用序列一致。

个人 SM2 电子签名认证证书 ​

  • 路径 {productId} 使用个人产品 ID(基础级 trustasia_ide_pic / 高等级 trustasia_ide_pipc)。
  • 请求体传 person_info:last_name(姓)、first_name(名)、id_type、id_number、telephone。
  • certificate.key_algo="SM2"、key_len=256。
  • 示例见创建订单 · 个人 SM2。

个人 RSA 电子签名认证证书 ​

  • 个人产品 ID,请求体同上传 person_info。
  • certificate.key_algo="RSA",key_len 取 2048 / 3072 / 4096(以产品配置为准)。
  • 示例见创建订单 · 个人 RSA。

机构 SM2 电子签名认证证书 ​

  • 路径 {productId} 使用机构产品 ID(基础级 trustasia_ide_bipc / 高等级 trustasia_ide_bipro)。
  • 请求体传 organization(name、uscc、地址等)与 organization.contact 经办人(id_type、id_number、telephone 必填)。
  • certificate.key_algo="SM2"、key_len=256。
  • 示例见创建订单 · 机构 SM2。

机构 RSA 电子签名认证证书 ​

  • 机构产品 ID,请求体同上传 organization 与经办人。
  • certificate.key_algo="RSA"、key_len 取 2048 / 3072 / 4096。
  • 示例见创建订单 · 机构 RSA。

三、签名流程 · 意愿确认签名 ​

  1. 调用发起签名意愿(POST /openapi/v3/esign/sign-wills,X-ES-Request-ID 必填;body:certId + files(文件名+哈希,可多个)+ hashAlg),同步取得 willId / confirmUrl / expireAt / willStatus;
  2. 将 confirmUrl 定向下发终端用户;用户浏览器直连云签意愿页,自选核验方式完成确认(口令 / TOTP / 短信 / 人脸,页面含口令时默认优先);
  3. 轮询查询意愿结果(3~5 秒间隔)至 willStatus=SIGNED 且 signStatus=SUCCESS,读取 signatures(fileName/dataHash/signature 一一对应)及 signId/signedAt/tsToken。

常见问题

  • SM2 证书的 dataHash 必须是 e 值 SM3(Z_A ‖ 文件原文),不是裸 SM3(文件原文)——传错接口不报错、验签才暴露,见签名数据格式与验签;
  • signerId 不传时由 CC 推导默认签署人(机构=经办人、个人=本人);机构证书委托代签时显式传持生效授权的委托人 delegateId(见六、委托代签);
  • 意愿未完成时可经取消意愿取消——仅签名(SIGN)意愿且用户尚未确认时可取消(reason 必填,HTTP 202 受理);其余类型或已确认 / 签名中 / 已完成的意愿取消返回 409 esign_upstream_rejected。

四、签名流程 · 预授权签名 ​

第一步 · 创建预授权 ​

  1. 调用创建预授权意愿(POST /openapi/v3/esign/sign-grants,X-ES-Request-ID 必填;certId + signTaskId + signerId + willDescription 授权告知文案必填——不携文件摘要,该文案是用户知情的唯一依据,在意愿页固定句式展示并纳入存证)。multiGrant 可选:
    • 缺省 false=单次:授权窗口可由调用方成组指定 grantCount / grantValidity / grantValidityUnit(缺一或超平台上限被拒;单位含分钟/小时/天/日历月/日历年),不传取平台默认(1 次 / 3 天);也可传 usageLimitEnable=false 设不限次数(只固化有效期、不得携带 grantCount)。均创建时固化、意愿页只读展示、不可修改;
    • true=多次:用户在意愿页自行设置次数与有效期(含有限 / 不限次数选择,受平台硬上限约束;此模式不得携带窗口参数,usageLimitEnable 以页面选择为准)。allowedModes 可选收紧;
  2. 同步返回 willId / confirmUrl / expireAt / confirmUrlExpireAt,下发用户;用户在页面阅读授权范围(固定句式 + 告知文案 + 次数 / 有效期)、勾选授权内容后完成核验(口令默认优先 / 短信 / 人脸 / TOTP);
  3. grantId 获取:回调 esign:grant_ready 主动推送,或经查询意愿结果按 willId 查询——businessStatus=SUCCEEDED 后返回 grantId 与 usageLimitEnable/usageLimit/usageRemaining/validUntil(不限次数不含两个次数字段;不含 Token);
  4. Token 获取:随 esign:grant_ready 回调交付,或经领取预授权 Token按 grantId 拉取(可重复领取、幂等交付)。Token 是敏感凭据(勿记日志、勿拼入 URL、勿存前端本地存储)且非一次性——额度窗口内可反复用于签名,直至耗尽 / 过期 / 撤销才失效。

第二步 · 携 Token 签名(同步返回) ​

  1. 每次签名调用凭预授权 Token 签名(X-ES-Request-ID 必填;grantToken + certId + signTaskId + signerId + files + hashAlg)——同步返回签名值与 grantId/usageRemaining/signedAt/tsToken(签名接口不返回 usageLimitEnable,次数模式以下一步的查询为准);有限次数一次调用固定扣减 1 次额度(与当次文件数无关),不限次数不扣减、响应不含 usageRemaining,同一 Token 在有效期内可并发反复签名;均无需终端用户逐次确认、无需轮询;
  2. 额度对账经查询预授权状态(usageLimitEnable/usageLimit/usageRemaining/validFrom/validUntil/lastUsedAt/status=ACTIVE / EXHAUSTED / EXPIRED / REVOKED,进入终态后 Token 同步失效;不限次数不返回两个次数字段、EXHAUSTED 不可达);
  3. 提前作废经撤销预授权(X-ES-Request-ID 必填)——返回撤销意愿 confirmUrl,本人页面确认后才置 REVOKED、剩余额度作废、Token 失效(确认前额度仍 ACTIVE、签名不受影响)。对已终态(已撤销 / 已过期 / 次数耗尽)的预授权再次撤销,或同一 certId + signTaskId 下已有待确认撤销意愿时再发起,都会被拒(409 esign_upstream_rejected)。

五、凭据管理(签署口令 PIN / 动态口令 TOTP) ​

两类凭据均按「发起意愿 → 用户本人在意愿页完成 → 查询生效」模型管理。personType 取值:ENTERPRISE_PERSON(企业人员:经办人(含亲自经办的法定代表人)/ 委托人)/ PERSONAL_SUBSCRIBER(个人订户本人);personId 按人员身份取值——个人订户本人取证书标识映射的 subjectId、企业经办人取 managerId、委托人取新增委托人响应的 delegateId。两类凭据对 certId 的要求不同:PIN 按「人员 × 证书」绑定——要求证书 NORMAL 且在有效期内(过期按证书有效期动态判定、同样被拒),委托人还须在该证书上有生效中的委托授权;TOTP 按人员维度绑定——certId 仅作归属校验锚点,不校验委托授权。

5.1 签署口令(PIN · 人员×证书绑定) ​

  1. 按操作调用对应接口(X-ES-Request-ID 必填;body:certId/personType/personId;allowedModes 可选收紧——PIN 类意愿不允许以 PIN 自证):创建 POST /openapi/v3/esign/pins · 修改 /pins/update · 清除 /pins/clear · 忘记重置 /pins/forgot(重置并解除锁定);
  2. 返回 confirmUrl 下发本人;本人在意愿页完成身份核验后自行设置口令值(创建 / 修改 / 忘记重置)或明确确认(清除);
  3. 轮询查询意愿结果至 businessStatus=SUCCEEDED 生效。锁定不自动解锁:经忘记重置或清除后重新创建恢复。

5.2 动态口令(TOTP · 人员维度绑定) ​

  1. 绑定:调用 POST /openapi/v3/esign/totp-bindings(参数同上;绑定场景不允许以 TOTP 自证)→ 返回 confirmUrl 下发本人;本人先经短信 / 人脸核身,再完成认证器扫码绑定与首码激活;
  2. 轮询至 businessStatus=SUCCEEDED 生效;可再经查询 TOTP 绑定状态复核(AVAILABLE / NOT_CONFIGURED / PENDING / LOCKED / DISABLED);
  3. 解绑:调用 POST /openapi/v3/esign/totp-bindings/unbind(可用待解绑的 TOTP 自证)→ 本人页面确认后删除绑定。锁定不自动解锁:经解绑后重新绑定恢复;接口不返回密钥、算法参数、计数器或错误次数。

六、委托代签(企业证书) ​

仅企业证书适用,个人证书不支持委托授权。委托代签让经办人之外的自然人(受托人)在授权生效期内代替经办人在指定证书上签署;代签只走一步轨——发起签名意愿时以 signerId=delegateId 指定由该委托人签署(两步轨预授权不支持委托人)。生效判据同其他意愿:以 businessStatus=SUCCEEDED 为准,willStatus=CONFIRMED 只代表双方确认完毕、业务尚在云签侧异步生效。

6.1 建立委托关系 ​

  1. (可选)调用查询企业人员(POST /openapi/v3/esign/enterprise-persons/query,纯查询、不需幂等键)定位候选人与 grantorPersonId(也可直接取证书标识映射查询的 managerId);
  2. 调用新增委托人(X-ES-Request-ID 必填;certIds 必填且非空、须同属一个企业订户,grantorPersonId 必填,delegate 对象必填——字段明细见接口页;validFrom/validTo 可选,缺省立即生效 / 长期有效);
  3. 双向意愿:返回一个 willId 与两条 confirmUrl(grantorConfirmUrl 下发经办人、delegateConfirmUrl 下发被委托人,同时有效、确认不限先后),同时返回 delegateId——这就是后续代签时要传的 signerId,务必保存。双方确认过程中 willStatus 依次为 PENDING → PARTIAL_CONFIRMED → CONFIRMED;该窗口内用相同的 X-ES-Request-ID 重复调用会幂等回放同一意愿的两条 confirmUrl,不会重复建单——链接丢失时据此重新取得;
  4. 生效以 businessStatus=SUCCEEDED 为准:经委托授权生效回调 esign:delegate_ready(交付 willId 与 delegateId;⚠️ 当前由 CertCloud 轮询云签结果驱动推送,不承诺时效),或轮询查询意愿结果(亦可按 requestId + willType=DELEGATE_CREATE 查询)。可再经查询委托授权记录核实逐证书明细:status=ACTIVE 且当前时间落在 [validFrom, validTo) 内才代表此刻可代签。

有效期重叠会被拒——按 conflicts[] 处理,不是重试

同一委托人在同一证书上的授权有效期不可重叠(含未设 validTo 的长期授权;首尾相接允许)。重叠时返回 409 esign_delegate_authorization_overlap,响应体 data.conflicts[] 逐条给出 certId / validFrom / validTo / conflictAuthorizationId。这是当前请求终态拒绝:原样重试无用,须据明细收窄 certIds 或调整时间窗,再换新的 X-ES-Request-ID 发起。详见新增委托人 · 错误码。

6.2 委托代签 ​

授权生效后,代签与普通签名完全同路:调用发起签名意愿,唯一差别是 signerId 传 delegateId(不传则仍推导为经办人);confirmUrl 下发给被委托人打开确认,轮询与终态判定同第三节。授权已过期 / 已撤销 / 尚未到 validFrom,或 signerId 既不是经办人也不是持生效授权的委托人时,返回 403 esign_person_not_in_scope。

6.3 停用委托人 ​

调用禁用委托人(POST /openapi/v3/esign/delegates/{delegateId}/disable,X-ES-Request-ID 必填;body 传 certId 作归属校验锚点 + grantorPersonId)——与新增不同,停用是经办人单方意愿,只返回一条 confirmUrl;经办人确认后轮询查询意愿结果至 businessStatus=SUCCEEDED,生效后经查询委托授权记录可见记录 status 转为 REVOKED。停用非删除:历史授权记录保留,但该委托人不再可代签,且停用按委托人生效、不区分证书。

七、轮询预算与限流 ​

本页每个阶段都要轮询。任务一多,最先撞上的往往不是业务错误,而是全局限流——它按客户端 IP 计,与账号、接口无关:同一出口 IP 上的所有轮询和业务调用共享同一份额度。

两个窗口 ​

窗口限值折算
长期3 分钟 1000 次平均 ≈ 5.5 次/秒
短期(突发)5 秒 100 次瞬时 20 次/秒

两个窗口同时生效,任一打满即触发限流。长期窗口决定「能并发多少条轮询」,短期窗口决定「能不能在同一瞬间发出去」——分别对应下面两节。

并发预算公式(长期窗口) ​

一条轮询任务每 T 秒发一次请求,占用 1/T 次/秒。由 N/T ≤ 5.5 得:

可并发轮询任务数  ≈  5.5 × 轮询间隔秒数
轮询间隔可并发任务数(上限)
3 秒约 16 条
5 秒约 27 条
10 秒约 55 条

超出就必须放大间隔或分批调度,否则长期窗口必然打满。这是整个出口 IP 的总预算:下单、发起意愿、查询映射等非轮询调用也占同一个池子,实际留给轮询的要再打折扣,建议按上表的 70% 规划。

轮询必须加 ±30% 抖动 ​

间隔再大也救不了同相定时器。 批量发起 N 个任务时,所有定时器从同一时刻起跳、周期又相同,于是每一轮都在同一瞬间集中发出 N 个请求——第 101 个请求就打穿「5 秒 100 次」的突发窗,与轮询间隔无关:间隔 3 秒会被限,间隔 60 秒同样会被限,只是撞墙的频率不同。

做法是每次计算下一次延迟时叠加 ±30% 随机抖动,让相位散开:

js
const base = 5000                                  // 基础间隔 5s
const next = base * (0.7 + Math.random() * 0.6)    // 实际 3500~6500ms
setTimeout(poll, next)

不要用「固定间隔 + 启动时一次性随机延迟」代替——那只散开首轮,之后相位重新固定,长跑中会再次聚拢。

命中 429 的处理 ​

触发全局限流时返回 HTTP 429,响应体是纯文本 rate limited.,不是 JSON——不要试图解析 code 字段,429 状态码本身就是唯一判据。(接口级限流不同:返回 400 + JSON code=request_too_fast,见调用频率限制。)

正确做法是全局暂停,不是逐任务重试:

  1. 读响应头 X-RateLimit-Reset(长期窗口重置的 Unix 时间戳),暂停该出口 IP 上的全部轮询直到该时刻;若响应未带该头,退化为固定退避——至少等满长期窗口的 3 分钟。
  2. 恢复后依据 X-RateLimit-Remaining 与 X-RateLimit-Remaining-Burst 自适应调速;若反复命中,说明并发预算超了,应永久调大间隔或减少并发任务数,而不是靠退避硬扛。
  3. 被限的那次请求不算业务失败——轮询目标的状态并未变化,恢复后照常继续轮即可。

不要对 429 逐任务立即重试

逐任务退避会让 N 条被限的任务在各自计时后再次聚到一起发起,形成重试风暴,把突发窗口继续压死、并不断延长限流时间。429 是全局信号,必须由一个统一的调度器接管所有轮询任务的节奏,而不是各任务各退各的。

调用方判定表 ​

阶段继续条件完成条件失败或停止条件
身份审核审核链接未过期、审核未出结果审核通过(此后可立即或延后下单)审核拒绝,或链接过期未完成
订单签发订单仍在处理中订单状态为 issued,随后进入映射与托管检查订单状态为 failed
标识映射certId 为空取得 certId;同时保存可用的 subjectId、managerId接口返回不可恢复错误
云签托管status=PENDING_ISSUE 且未返回 hostingFailedstatus=NORMALhostingFailed:true(托管重试已停止、状态永久不变,须转人工)、VOIDED(待签发记录已作废)、其它终态,或任何未知取值
签名意愿(一步)willStatus、signStatus 均未进入终态willStatus=SIGNED 且 signStatus=SUCCESS,读取 signatures任一状态为 FAILED、CANCELLED 或 EXPIRED
预授权 / 凭据 / 委托意愿用户未确认(委托为双方均未确认完毕),或确认后 businessStatus 仍未终结businessStatus=SUCCEEDEDbusinessStatus=FAILED,或意愿为 FAILED、CANCELLED、EXPIRED;委托新增另有 409 esign_delegate_authorization_overlap(终态拒绝,须改参数换新幂等键)

关键规则 ​

  • 身份审核先行,审核与签发解耦:终端用户在平台发起身份审核时,调用方通过创建审核链接获取 access_url 渲染到平台页面,由用户/机构在审核页完成身份审核、证书签发意愿确认、私钥托管意愿确认、签名意愿确认方式选择等;进度与结果经获取审核链接详情查询。审核通过后,签发请求可以紧接发起,也可以延后另行发起。
  • 申请入口是创建订单,签发是异步过程(CertCloud 内部完成 CSR 获取、CA 签发与云签托管)。路径中的 {productId} 是产品 ID,返回的 data.id 才是后续查询使用的 orderId。
  • 个人与机构证书均支持 SM2、RSA,实际可选算法和 RSA 密钥长度以账户开通的产品配置为准。certificate.csr_from 必须为 esign,不得提交 CSR、私钥或 encrypted_key。
  • X-ES-Request-ID 是发起类写接口的幂等键。发起类写接口的上游错误统一为 HTTP 409:code=esign_upstream_error 为暂时性失败,可保持请求内容并使用相同 ID 重试;code=esign_upstream_rejected 为当前请求终态拒绝,应修正问题后使用新的 ID。两者同为 HTTP 409,能否重试须依据响应 code 区分,不能只看 HTTP 状态码;错误文案只供人工排查。
  • 平台不与云签直接交互:意愿与签名状态的查询入口只有 CertCloud 的 查询意愿结果(GET /openapi/v3/esign/wills/{willId}),它直接返回 CertCloud 内部调度轮询云签后落库的最新快照;对云签的查询(B2)是 CertCloud 内部行为,云签接口不对公网暴露、平台无法也无需直连。唯一由外部直连云签的场景是终端用户浏览器打开 confirmUrl 意愿确认页。
  • confirmUrl 是云签一次性短链,只能定向发送给对应终端用户,不得缓存、记录日志或公开传播。
  • 证书状态轮询只有一条继续条件:status === "PENDING_ISSUE" 且 hostingFailed !== true。其余一切——NORMAL(就绪)、hostingFailed:true、VOIDED(待签发记录已作废)、FROZEN / REVOKED,以及任何未知取值——都应立即停轮,按「不是 NORMAL 就继续轮」实现会死循环。见停轮公式。
  • 销毁要求证书已撤销(REVOKED)或已过期:顺序为「轮询查询证书状态确认 REVOKED(或 expired=true)→ 发起销毁意愿、控制人确认 → 轮询 businessStatus=SUCCEEDED」。对未过期的 NORMAL / FROZEN 态证书直接发起销毁会被终态拒绝(409 esign_upstream_rejected,[-5013] 意愿绑定证书不可用)。
  • 签名数据格式:dataHash 为十六进制小写摘要,SM2 证书须提交 e 值(e = SM3(Z_A ‖ 文件原文)),RSA 为 SHA256/384/512(文件原文);signature 为 Base64 原始签名值,SM2=ASN.1 DER SEQUENCE { r, s }、RSA=PKCS#1 v1.5。SM2 口径传错不会在接口层报错,只在验签时暴露。见签名数据格式与验签。
  • 销毁的 reason 必填且非空白(缺失、空串或纯空格均被拒、不创建意愿,最长 512 字符)。reason 进入审计留痕,勿传占位符或统一默认文案。云签侧的撤销原因首次写入后不再更改。
  • 签名与凭据的人员标识来自证书标识映射:个人证书使用 PERSONAL_SUBSCRIBER 与 subjectId,机构证书使用 ENTERPRISE_PERSON 与 managerId;签名意愿的 signerId、凭据管理的 personType / personId 均据此填写。例外:一步轨发起签名意愿的 signerId 在机构证书上还接受持有生效委托授权的委托人 delegateId(委托代签);两步轨的 signerId 无此扩展,必须是经办人 / 订户本人。另需注意:ENTERPRISE_PERSON 在上游为统称口径——经办人(含亲自经办的法定代表人,无独立法人 ID)与委托人;凭据管理接口的 personId 按人员身份取 managerId 或委托人的 delegateId(PIN 要求委托人在该证书上有生效中的委托授权,TOTP 不校验委托授权),详见第五节「凭据管理」。
  • 预授权与凭据管理不能把 willStatus=CONFIRMED 当成完成;必须继续查询到 businessStatus=SUCCEEDED 或 FAILED 才算业务生效。