西藏巴青项目

应用密码改造技术方案.md 13KB

应用密码改造 — 技术方案

巴青牧业数字化平台国密合规改造总体技术方案。
依据等保及行业密码应用要求:身份鉴别对接签名验签服务器;存储加解密对接密码机;完整性校验与篡改告警。


1. 技术架构

说明
整体 RuoYi v3.9.2(springboot2)单体 + Vue2 管理端 + 移动端/App
运行时 JDK 8、Spring Boot 2.x、Spring Security、MyBatis、Redis
数据库 MySQL 5.7+,InnoDB,utf8mb4
密码设施 签名验签服务器(SM2 验签)、密码机 HSM(SM3-HMAC、SM4)
短信 互联网管理端双因子(账号口令 + 短信验证码)

1.1 逻辑架构

flowchart TB
    subgraph client [客户端]
        UKey[国密 UKey]
        Browser[管理端浏览器]
        App[移动端/App]
    end

    subgraph app [应用层 baqing-admin]
        LoginGW[登录网关]
        CertLogin[证书登录]
        SmsLogin[短信双因子登录]
        AuthFilter[Spring Security 过滤器链]
        CryptoSDK[CryptoService 密码服务封装]
        IntegritySvc[IntegrityService 完整性服务]
        MyBatisCrypto[MyBatis 加解密拦截器]
        AlertSvc[SecurityAlertService 告警]
    end

    subgraph external [外部设施]
        SignServer[签名验签服务器]
        HSM[密码机]
        SMS[短信网关]
    end

    subgraph storage [存储]
        DB[(MySQL)]
        Redis[(Redis)]
    end

    Browser --> LoginGW
    UKey --> SignServer
    CertLogin --> SignServer
    SmsLogin --> SMS
    LoginGW --> AuthFilter
    AuthFilter --> CryptoSDK
    MyBatisCrypto --> CryptoSDK
    IntegritySvc --> CryptoSDK
    CryptoSDK --> HSM
    IntegritySvc --> DB
    AlertSvc --> DB
    LoginGW --> Redis

1.2 设计原则

原则 说明
密钥不出机 主密钥仅存密码机,应用仅持有密钥索引 keyIndex
统一封装 业务代码禁止直接调用厂商 SDK,统一经 CryptoService
分类分级 按数据类型选择「仅完整性」或「机密性 + 完整性」
可审计 验签、加解密、校验失败均记安全日志,日志本身做 HMAC
可演进 支持密钥版本 key_ver 轮换与存量数据重算

2. 身份鉴别改造

2.1 登录策略矩阵

场景 用户类型 最低要求 说明
内网/专网管理端 系统管理员 国密 UKey 证书 对接签名验签服务器 SM2 验签
互联网管理端 系统管理员 账号口令 + 短信验证码 双因子,缺一不可
业务操作员 按角色配置 口令 + 可选短信/UKey sys_login_policy 配置
移动端/App 普通用户 现有口令/Token 体系 敏感接口可增加短信二次确认

2.2 管理员 UKey 证书登录流程

sequenceDiagram
    participant U as 管理员浏览器
    participant C as UKey控件/中间件
    participant API as baqing-admin
    participant SS as 签名验签服务器
    participant R as Redis

    U->>API: GET /login/cert/challenge
    API->>R: 存 challenge(TTL 5min)
    API-->>U: challenge
    U->>C: 读取证书 + SM2 签名(challenge)
    C-->>U: certBase64 + signedData
    U->>API: POST /login/cert {cert, signedData, challenge}
    API->>SS: 验签(cert, signedData, challenge)
    SS-->>API: 验签结果
    API->>API: 按 cert_sn 查 sys_user
    API-->>U: JWT Token
    API->>API: 写 sys_logininfor + 安全审计

后端改造点

模块 改造内容
SysLoginController 新增 GET /login/cert/challengePOST /login/cert
sys_user 增加 cert_sncert_subjectlogin_policy
TokenService 证书登录成功后与普通登录共用 JWT 签发逻辑
SysLoginService 增加 loginByCertverifyCertSignature
权限 超级管理员角色可配置强制证书登录

验签失败处理

  • 记录 sys_logininfor(失败原因:验签失败/证书过期/用户未绑定)
  • 连续失败 N 次触发 IP 限流(复用现有登录失败策略)

2.3 互联网双因子登录(口令 + 短信)

流程

  1. POST /login/sms/send:校验图形验证码 → 发送短信 OTP 至 sys_user.phonenumber
  2. POST /login:提交 usernamepasswordsmsCode(及图形验证码)
  3. 校验短信 OTP(Redis)→ 校验口令(BCrypt)→ 签发 Token,写登录日志

改造点(一期已实施)

说明
Redis Key login:sms:{mobile} / login:sms:limit:{ip}
OTP 规则 6 位数字,5 分钟有效,校验成功后一次性删除
sys_user.phonenumber 一期读明文列;二期可改为 SM4 解密
双因子总开关 login.auth-mode: sms-2falogin.internet-sms.enabled: true
若依默认登录 login.auth-mode: ruoyi单配置项恢复改造前行为)
策略表 sys_login_policy + login.network-zone
短信网关 AliyunSmsGatewayClientalibabacloud-dysmsapi20170525
开发 Stub sms.aliyun.dry-run=true 时仅写日志,关键字 【短信Stub】

后端类路径

模块
LoginSmsService ruoyi-framework
SysLoginService.login(..., smsCode) ruoyi-framework
SysLoginController baqing-admin
SysLoginPolicyServiceImpl ruoyi-system
AliyunSmsGatewayClient ruoyi-framework

详见 配置与接口说明.md

2.4 与现有 RuoYi 权限衔接

  • 身份鉴别仅解决「你是谁」;授权仍走 sys_role / sys_menu / @PreAuthorize
  • 权限相关表纳入完整性保护(见第 4 节),防止越权篡改

3. 密码机对接 — 存储加密

3.1 模块划分(ruoyi-crypto,一期已建)

ruoyi-crypto/
├── config/
│   ├── CryptoProperties.java          # 密码机连接、密钥索引
│   └── CryptoAutoConfiguration.java   # Spring Boot 自动配置
├── enums/
│   └── CryptoDataType.java
├── service/
│   ├── CryptoService.java             # 统一对外接口
│   └── impl/StubCryptoServiceImpl.java  # 开发态 Stub(BouncyCastle)
└── exception/
    └── CryptoException.java

生产环境将 StubCryptoServiceImpl 替换为厂商 HSM SDK 实现,接口不变。

3.2 统一服务接口(概念)

public interface CryptoService {
    /** SM3-HMAC,返回 Base64 */
    String hmacSm3(byte[] plain, int keyIndex, CryptoDataType dataType);

    /** SM4 加密,返回 Base64 密文 */
    String encryptSm4(String plainText, int keyIndex, CryptoDataType dataType);

    /** SM4 解密 */
    String decryptSm4(String cipherText, int keyIndex, CryptoDataType dataType);

    /** 完整性校验 */
    boolean verifyHmac(byte[] plain, String storedHmac, int keyIndex, CryptoDataType dataType);
}
  • keyIndex:密码机内密钥槽位,按数据类型分钥(见《配置与接口说明.md》)
  • 所有调用记 sys_crypto_audit_log(操作类型、dataType、结果,不含明文

3.3 数据保护策略总表

数据类别 SM3 HMAC 完整性 SM4 机密性 说明
身份鉴别数据 账号口令、登录相关敏感配置
个人信息 姓名、手机、邮箱、证件号等
权限信息 用户、角色、菜单关联(一般不需 SM4)
操作日志 操作内容摘要做 HMAC,防删改
主要业务数据 产业各业务表敏感列

详细字段见 数据分类与字段加密映射表.md

3.4 存储模型

机密性字段(SM4)

原列改为存密文,或新增 *_cipher 列:
  phonenumber_cipher   VARCHAR(256)   -- SM4 Base64 密文
  phonenumber_hmac     VARCHAR(128)   -- SM3 HMAC
  crypto_key_ver       INT            -- 密钥版本,轮换用

仅完整性字段(SM3)

行级或逻辑组:
  integrity_hmac       VARCHAR(128)
  integrity_key_ver    INT

Canonical 拼接规则(HMAC 输入,必须固定)

payload = dataType + "|" + keyVer + "|" + field1 + "|" + field2 + "|" ...
  • 字段顺序、空值用固定占位符(如 <NULL>)写入规范文档,版本升级时兼容旧 key_ver

3.5 写入 / 读取拦截

方式 适用 说明
MyBatis 拦截器 推荐 sys_crypto_field_config 自动加解密、写 HMAC
Service AOP 补充 @CryptoField@IntegrityProtected 注解
定时任务 存量迁移 批量重加密、重算 HMAC

写路径

  1. 业务 Service 提交明文实体
  2. 拦截器查配置 → SM4 加密敏感列 → SM3 计算 HMAC → 写库

读路径

  1. 拦截器读密文 → SM4 解密
  2. 重算 HMAC 与库中比对 → 不一致则告警并阻断(见第 5 节)

3.6 口令存储说明

方案 说明
测评要求 SM4 存口令 password 列存 SM4 密文;登录时解密后比对或调密码机专用校验接口
测评允许单向摘要 保留 BCrypt,传输链路与备份用国密;存储层按测评口径二选一

实施前必须与测评机构确认口径,并在映射表中定稿。


4. 完整性校验与篡改告警

4.1 校验时机

时机 动作
读时校验 查询解密后重算 HMAC,与库中 *_hmac 比对
写前校验 更新前先校验旧记录完整性,失败则拒绝更新
登录/鉴权 加载用户、角色、菜单权限前校验关联数据完整性
定时巡检 夜间全表/抽样校验,发现静默篡改

4.2 校验流程

读取记录
  → 若含密文字段:SM4 解密得明文
  → 按 Canonical 规则拼接待保护串
  → 调密码机 SM3-HMAC
  → 与 integrity_hmac / 字段 hmac 比较
  → 不一致 → 记安全事件 + 告警 + 业务阻断/降级

4.3 告警分级

级别 场景 系统动作
用户口令、角色权限被篡改 阻断访问、锁定账号、通知安全管理员
个人信息、业务主数据篡改 拒绝写操作、页面提示、记安全事件
单条操作日志 HMAC 失败 记事件、不影响其他业务只读

4.4 用户提示文案(产品)

  • 管理端:数据完整性校验失败,疑似被非法篡改,请联系系统管理员。
  • 不向用户展示 HMAC、密钥索引等内部信息

4.5 告警通道

  • sys_security_alert 持久化
  • 对接:站内消息(若依通知)、短信、运维监控平台
  • sys_oper_log 区分:后者为业务操作日志,前者为密码/完整性安全事件

5. 与现有工程的集成点

现有模块 集成方式
ruoyi-framework / TokenService 登录成功后触发权限数据完整性抽检(可选)
ruoyi-system / SysUserService 用户增删改走加解密拦截器
LogAspect / sys_oper_log 写入后异步计算行 HMAC
baqing-adminbiz_* 业务 按映射表配置敏感字段
ruoyi-quartz 完整性巡检任务 CryptoIntegrityJob

6. 非功能要求

要求
性能 密码机连接池;批量读可做短 TTL 校验结果缓存(须评估安全)
高可用 密码机双机热备;SDK 支持 failover
密钥轮换 key_ver 递增;后台任务重算 HMAC / 重加密
审计 所有密码调用、验签、校验失败可追溯
灾备 密钥备份恢复流程与等保测评一致

7. 分期实施(概要)

详见 实施计划与验收.md

期次 内容 状态
一期 短信双因子后端、ruoyi-crypto Stub、阿里云短信 SDK、auth-mode 切换 ✅ 后端已完成
一期余 UKey 证书登录、前端登录页
二期 sys_user / 权限表 / 日志表 SM3;个人信息 SM4
三期 业务表按映射表改造;存量迁移
四期 定时巡检、告警中心、密钥轮换

8. 风险与注意事项

  1. 禁止应用内硬编码密钥;仅使用密码机密钥索引。
  2. 权限表篡改危害最大,必须读时 + 写后 + 定时三重校验。
  3. 日志防删改:HMAC + 考虑独立审计库或只追加存储。
  4. Canonical 规则变更须升 key_ver,避免误报。
  5. 改造前先评审《数据分类与字段加密映射表》,再动表结构。
  6. 厂商 SDK 线程安全与连接泄漏需在压测阶段验证。