3. 医保支付接口安全机制
医保支付接口承载参保人身份、处方明细、结算金额与基金支付结果,一旦被篡改、重放或泄露,后果直接落到基金安全和患者隐私上。因此,接口安全不是"加个 HTTPS 就行",而是由身份可信、内容不可篡改、传输不可窃听、请求不可复用、数据不可滥用五条防线共同构成的体系。本节按"一次结算请求从发出到被受理"的真实链路,逐层说明每道防线解决什么问题、用什么技术实现、工程上如何落地。
一、数字签名:证明"是谁发的、内容有没有被改"
医保接口普遍采用非对称签名:定点机构用自己的私钥对请求报文签名,医保平台用该机构的公钥验签。签名保证两件事——身份可追溯(只有持私钥的一方能签出)和完整性(报文任一字节变化,验签必然失败)。
工程实现上,签名不是对整段 JSON 直接签,而是先规范化再签,否则字段顺序、空格差异会导致验签失败。典型做法是:剔除 sign 字段后,将参与签名的参数按 key 的 ASCII 升序拼接成 k1=v1&k2=v2&...,再拼接 &key=商户密钥(或直接对拼接串做摘要),最后用私钥签名。摘要算法常用 SHA-256,签名算法常用 RSA2048/SM2。示例参数如下:
待签串:appId=H510100001&bizNo=JS20240612001&amt=128.50&ts=1718179200
摘要:SHA-256(待签串) → 32 字节
签名:SM2_Sign(摘要, 机构私钥) → Base64 后放入 sign 字段
验签:SM2_Verify(摘要, sign, 机构公钥) → true / false
判断依据很直接:验签通过才进入业务处理;验签失败一律拒绝并记录 sign_verify_fail 事件,不返回任何业务细节,避免成为探测工具。注意签名只解决"真伪与完整",不解决"保密",报文内容仍是明文,需要下一层加密。
二、证书管理:公钥的信任来源
公钥怎么可信地交给对方?靠数字证书。医保侧通常由省级平台或 CA 机构签发机构证书,证书里绑定机构编码、公钥、有效期和用途。工程上要管好四件事:申请与下发、有效期监控、轮换与吊销、存储保护。
证书过期是生产事故高发点。建议在到期前 60 天、30 天、7 天分级告警,并支持双证书并行期——新证书先上线验签,旧证书保留一段时间,避免切换瞬间全量失败。私钥必须放在加密机、KMS 或至少是受权限保护的密钥库中,禁止硬编码在代码或配置文件里。证书吊销(如私钥疑似泄露)后,平台侧应能通过 CRL/OCSP 或本地黑名单立即拒绝该证书的请求。
三、加密传输:让报文在链路上"看不懂"
传输层用 TLS 1.2/1.3 是底线,需禁用 SSLv3、TLS 1.0/1.1 和弱套件,并做证书双向校验(mTLS),使双方都验证对端证书。但仅有 TLS 不够:报文可能在网关、日志、代理处落地为明文。因此对敏感字段还要做应用层加密,常用 AES-128/256-GCM 或国密 SM4,密钥通过平台公钥加密后随报文传输(数字信封),或双方预置对称密钥并定期轮换。
下面这张图给出一次医保结算请求的完整安全链路,从签名、加密、令牌、防重放到脱敏,各环节的输入输出与校验点一目了然:
四、令牌与鉴权:控制"能做什么"
签名解决身份真伪,令牌解决权限范围。医保平台一般先通过 appId + 密钥 换取 access_token,token 中携带机构编码、可访问的接口清单、有效期(常见 7200 秒)。调用业务接口时在 Header 中带 Authorization: Bearer <token>。工程要点:token 必须服务端缓存并支持提前刷新,避免每次请求都换 token;token 与机构绑定,禁止跨机构复用;对高敏接口(如退费、冲正)可要求二次鉴权或独立授权码。
五、防重放攻击:让旧请求"过期作废"
攻击者截获一个合法请求后原样重发,若平台不识别就会重复扣款或重复支付。防重放靠三件套:时间戳 ts、随机数 nonce、请求唯一号 bizNo。平台校验规则通常是:|now - ts| ≤ 300 秒,且 nonce 在有效窗口内未被使用过,且 bizNo 未处理过。三者任一不满足即拒绝。nonce 需存入 Redis 等带过期能力的存储,TTL 略大于时间窗口(如 360 秒),避免无限增长。注意时间同步:机构与平台应通过 NTP 对齐,否则窗口过小会误杀正常请求。
六、敏感信息脱敏与合规要求
医保数据属于个人敏感信息,受《个人信息保护法》《数据安全法》及医保行业规范约束。核心原则是最小必要、全程可审计、能脱敏不落地明文。具体做法:
- 传输中:身份证号、手机号、银行卡号等字段用应用层加密,不以明文过网关。
- 展示与日志中:身份证保留前 6 后 4(如
5101**********1234),手机号保留前 3 后 4(138****5678),姓名保留姓氏(张*)。 - 存储中:敏感字段加密存储,密钥与数据分离;日志系统禁止打印完整报文,需在日志组件层做统一脱敏。
- 审计:记录谁在何时访问了哪些参保人数据,保留期符合监管要求,支持追溯。
七、落地检查清单
| 防线 | 关键动作 | 失败判断 |
|---|---|---|
| 数字签名 | 规范化拼接 + SHA-256/SM2 签名,响应同样签名 | 验签失败,拒绝并记 sign_verify_fail |
| 证书管理 | 到期前 60/30/7 天告警,双证书并行轮换 | 证书过期或吊销,请求被平台拒绝 |
| 加密传输 | TLS 1.2+ 与 mTLS,敏感字段 AES-GCM/SM4 | 握手失败或密文解密异常 |
| 令牌鉴权 | token 绑定机构与接口范围,提前刷新 | 401/403,权限越界被拦截 |
| 防重放 | ts 窗口 300 秒 + nonce 唯一 + bizNo 幂等 | 重复请求被识别,返回重放错误码 |
| 脱敏合规 | 传输加密、展示掩码、日志统一脱敏、访问审计 | 日志或库中出现明文敏感字段即不合规 |
这六道防线不是可选项,而是医保支付接口上线的前置条件。实际集成时建议先用沙箱环境逐项验证:构造一条正常请求确认全链路通过,再分别构造篡改报文、过期时间戳、重复 nonce、越权 token 四类异常请求,确认平台均能正确拒绝并返回可区分的错误码。只有异常路径也被验证过,安全机制才算真正生效。