cisd/README.md
2026-05-14 11:10:31 +08:00

574 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# TMS Framework
Single-process TMS monolith scaffold built with:
- JDK 17
- Spring Boot 3.5.x
- MyBatis-Plus
- TiDB (MySQL driver)
- Swagger (springdoc-openapi)
## Quick Start
```bash
cd tms-framework
mvn spring-boot:run
```
## Jar 包部署(外置配置)
完整部署手册:
- [docs/deployment/tms-deployment.md](/Users/waner/Work/CISD/文档/tms-framework/docs/deployment/tms-deployment.md)
1. 构建 jar 包:
```bash
cd tms-framework
mvn -q -DskipTests package
cp target/tms-framework-*.jar /home/tms/tms-framework.jar
```
2. 在 CentOS 上准备部署目录:
```bash
sudo mkdir -p /home/tms/{bin,config,scripts,logs,run}
sudo mkdir -p /home/tms/bin/resource-restore
sudo chown -R "$(whoami)":"$(whoami)" /home/tms
cp scripts/tms.sh /home/tms/scripts/tms.sh
cp scripts/standard-init/*.sh /home/tms/bin/
cp scripts/resource-restore/*.sh /home/tms/bin/resource-restore/
cp config/application.yml.example /home/tms/config/application.yml
chmod +x /home/tms/bin/*.sh
chmod +x /home/tms/bin/resource-restore/*.sh
chmod +x /home/tms/scripts/tms.sh
```
3. 启动 / 停止 / 状态:
```bash
/home/tms/scripts/tms.sh start
/home/tms/scripts/tms.sh status
/home/tms/scripts/tms.sh stop
```
说明:
- 脚本默认 `APP_HOME=/home/tms`,并通过 `--spring.config.additional-location=optional:file:<app_home>/config/``/home/tms/config/` 读取外部配置。
- 默认要求 `/home/tms/config/application.yml` 存在。
- 脚本不再强制指定 profile默认按 Spring 配置文件自身规则解析,可通过 `SPRING_PROFILES_ACTIVE=dev /home/tms/scripts/tms.sh start` 显式覆盖。
- 可通过 `JAR_PATH=/home/tms/tms-framework.jar` 覆盖 jar 路径。
- 如果部署路径不是 `/home/tms`,使用 `APP_HOME=/your/path /your/path/scripts/tms.sh start`
- 标准 CISD 初始化辅助脚本位于 `scripts/standard-init/`,部署时需复制到 `/home/tms/bin/`
- 资源恢复辅助脚本位于 `scripts/resource-restore/`,部署时需复制到 `/home/tms/bin/resource-restore/`
- `apply_standard_db.sh` 依赖预置环境变量,例如 `DB_USER`、`DB_PASSWORD`,不要直接写入 `application.yml`
- 运行目录结构、配置项说明、文件上传 `fileId` 流程和故障排查,请查看上面的完整部署手册。
## 配置敏感信息加密
配置文件中的敏感值可以写成 `ENC(...)`,应用启动早期会自动解密后再交给 Spring 绑定:
```yaml
spring:
datasource:
password: ENC(v1:<iv>:<ciphertext>)
```
当前实现使用 `AES-256-GCM`,主密钥按当前交付要求临时硬编码在代码中。生成密文:
```bash
java -jar tms-framework.jar --tms.crypto.encrypt
```
命令会从标准输入读取一行明文并输出 `ENC(...)`。解密校验:
```bash
java -jar tms-framework.jar --tms.crypto.decrypt
```
生产加固时应把硬编码密钥替换为环境变量、独立密钥文件或密码机/KMS 托管密钥。
运行时建议:
- 本地构建和测试统一使用 JDK 17与项目和 CI 运行时保持一致。
Open:
- Swagger UI: http://localhost:8080/swagger-ui.html
- Internal API docs JSON: http://localhost:8080/v3/api-docs/internal-api
- Runtime-generated Swagger/OpenAPI docs are the source of truth for `/api/**`.
- Internal health API: `GET /api/v1/device/status`
- Internal sign preview API: `POST /api/v1/sign/preview`
- External sign API: `POST /openapi/v1/sign/signature`
- Init template API: `GET /api/v1/init/template`
- Init preview API: `POST /api/v1/init/preview`
- Current init config API: `GET /api/v1/init/config`
- Reset preview API: `POST /api/v1/init/reset/preview`
- Reset create task API: `POST /api/v1/init/reset/tasks`
- Reset execute API: `POST /api/v1/init/reset/tasks/{taskId}/execute`
- Auth login API: `POST /api/v1/auth/login`
- Compat password login API: `POST /api/v1/auth/password-login`
- Compat UKey login API: `POST /api/v1/auth/ukey-login`
- Compat UKey random API: `GET /api/v1/auth/ukey-login/randoms`
- UKey binding issue-sign API: `POST /api/v1/auth/roles/{roleCode}/ukeys/issue-sign`
- UKey binding API: `POST /api/v1/auth/roles/{roleCode}/ukeys/bind`
- Device info API: `GET /api/v1/device/info`
- Device profile API: `GET /api/v1/device/profile`
- Device runtime status API: `GET /api/v1/device/runtime-status`
- Upgrade package upload API: `POST /api/v1/upgrade-packages`
- Upgrade preview API: `POST /api/v1/upgrades/previews`
- Upgrade create task API: `POST /api/v1/upgrades`
- Upgrade execute API: `POST /api/v1/upgrades/{taskId}/execute`
- Upgrade list API: `GET /api/v1/upgrades`
- CRL import API: `POST /api/v1/crls/import`
- CRL import task detail API: `POST /api/v1/crls/import-tasks/detail`
- CRL revoked list API: `POST /api/v1/crls/list`
- CRL delete API: `POST /api/v1/crls/delete`
- PCIe crypto count API: `GET /api/v1/device/crypto/device-count`
- PCIe crypto HMAC API: `POST /api/v1/device/crypto/hmac`
## Certificate CRL Management
前后端对接文档:
- [docs/openapi/certificate-frontend-integration.md](/Users/waner/Work/CISD/文档/tms-framework/docs/openapi/certificate-frontend-integration.md)
最小调用顺序:
- `POST /api/v1/crls/import`
- `POST /api/v1/crls/list`
- `POST /api/v1/crls/delete`
当前实现边界:
- 可通过 `tms.cert.trusted-root-fingerprints` 配置根 CA 证书 SHA-256 指纹白名单;配置后根 CA 导入必须命中白名单,中间 CA 仍按当前可信链校验。
- CRL 文件支持 PEM / DER 格式,导入接口会先创建后台任务并返回 `taskId`,前端通过 `POST /api/v1/crls/import-tasks/detail` 轮询 `PENDING/RUNNING/SUCCESS/FAILED` 状态。
- 后台导入完成后保存 CRL metadata 和 CRL 内每条 revoked certificate 明细;原始 CRL 文件只作为临时文件参与解析,任务结束后删除,不作为业务数据长期保存。
- CRL issuer 通过可信 CA 的 issuer DN 候选和实际 CRL 签名验证解析。
- CRL issuer 必须是可信 CA且 KeyUsage 必须允许 `cRLSign`
- 重复 CRL 通过 SHA-256 fingerprint 拒绝。
- revoked 明细查询按 `algoType` 和证书 `subjectDn` 模糊过滤,返回的是 revoked certificate 明细列表,不是 CRL 文件列表。
- 证书导入时如果 `issuerDn + serialNumber` 已命中已导入 CRL会拒绝导入。
- 证书列表和详情的 `runtimeStatus` 在 CRL 命中时优先返回 `REVOKED`,优先级高于时间有效期状态。
## CISD Reset
最小调用顺序:
- `POST /api/v1/init/reset/preview`
- `POST /api/v1/init/reset/tasks`
- `POST /api/v1/init/reset/tasks/{taskId}/execute`
- `GET /api/v1/init/reset/tasks/{taskId}`
- `GET /api/v1/init/reset/tasks/{taskId}/steps`
- `GET /api/v1/init/reset/tasks/{taskId}/steps/{stepNo}/log`
当前支持范围:
- 仅支持设备预置产品类型为 `ENTERPRISE``INDIRECT`
- `DIRECT` 当前明确不支持 reset
请求说明:
- reset 接口不再要求前端重复提交机构号、MQ 类型和 RabbitMQ 通道用户
- 后端会自动读取“最近一次成功初始化任务”的快照,提取 `orgCode`、`mqType`、`channelUsername`
- 如果当前设备没有有效初始化快照reset 预检和任务创建会直接失败
设备状态接口:
- `GET /api/v1/device/status`
- 返回字段 `initState`
- `UNINITIALIZED`: 当前没有有效初始化快照
- `INITIALIZING`: 初始化任务正在执行
- `INITIALIZED`: 当前设备已初始化
- `RESETTING`: 重置任务正在执行
- 前端仅根据 `initState` 判断展示初始化页、已初始化页或执行中页面
当前初始化配置展示接口:
- `GET /api/v1/init/config`
- 数据来源固定为最新一次成功初始化任务快照
- 只返回机构信息、部署信息、中间件信息和节点/签名核心字段
- 只用于展示,不用于编辑
当前 reset 实际会做的事情:
- 停止 `CMSP/CMTP`
- 删除数据库 `CMEP`
- 删除数据库 `orgCode`
- 删除 RabbitMQ 客户化账号、`/RQ` 权限、客户化队列
- 停止 RabbitMQ 进程
- 删除 TLQ license 文件
- 清理当前 reset 任务的 staging 目录
当前 reset 不做的事情:
- 不回滚 `cpconfig.cfg`
- 不删除 nginx 配置和已发布前端目录
- 不回滚应用配置文件中的 RabbitMQ 账号密码
- 不删除标准安装介质目录
运维前置条件:
- `scripts/standard-init/*.sh` 已部署到 `/home/tms/bin/`
- `/home/tms/bin/stop_standard_apps.sh`
- `/home/tms/bin/stop_standard_rabbitmq.sh`
- `/home/tms/bin/apply_standard_db.sh`
- `tms.init.executor.standard-db-username/password` 已正确配置
- `tms.init.executor.rabbitmq-ctl-command` 指向可执行的 `rabbitmqctl`
- 运行时 Swagger 文档以 `http://<ip>:8080/swagger-ui.html``http://<ip>:8080/v3/api-docs/internal-api` 为准
## Offline Upgrade
最小调用顺序:
- `POST /api/v1/upgrade-packages`
- `POST /api/v1/upgrades/previews`
- `POST /api/v1/upgrades`
- `POST /api/v1/upgrades/{taskId}/execute`
- `POST /api/v1/upgrades/{taskId}/rollback`
- `GET /api/v1/upgrades`
- `GET /api/v1/upgrades/{taskId}`
- `GET /api/v1/upgrades/{taskId}/log`
当前支持范围:
- 仅支持离线升级
- 当前支持任务类型:
- `TMS`
- `RECEIVER`
- `FIRMWARE`
- 当前不支持:
- 在线升级
- `CVE` / 操作系统补丁升级
当前流程:
- 先上传离线升级包,复用现有文件上传能力,得到 `fileId`
- 后端基于 `fileId` 解析升级包并做预检
- 预检结果返回 `taskType`、`productType`、当前版本、目标版本和版本变化提示
- 用户确认后创建升级任务
- 调用执行接口后,任务异步进入后台执行
- 升级失败后,如升级包提供 `rollback` 入口,可手工调用回滚接口
- 前端通过列表、详情和日志接口轮询任务状态
当前升级包要求:
- 外层为 zip 包
- 至少包含:
- `manifest.json`
- `signature.sig`
- `payload/` 下按需包含:
- `app/`
- `web/dist/`
- `config/`
- `sql/`
- `firmware/`
- `scripts/`
- 外层升级包实际包含的是 `payload.zip``payload.zip` 内部再包含上述 `payload/` 目录
- `signature.sig` 需要能被配置的 PEM 公钥使用 `SM3withSM2` 软验签通过
- 服务端需要配置 `tms.upgrade.signature-public-key-pem-path`(公钥 PEM 文件路径)
- `manifest.json` 当前要求包含:
- `packageId`
- `taskType`
- `productType`
- `version`
- `minCompatibleVersion`
- `description`
- `entrypoints.execute`
- `payloadSm3`
- 可选 `entrypoints.precheck`
- 可选 `entrypoints.verify`
- 可选 `entrypoints.rollback`
- `payloadSm3` 是整个 `payload.zip` 文件的 `SM3` 摘要;后端验签 `manifest.json` 后,会校验 `payload.zip` 摘要并解压出 `payload/` 供脚本执行
当前执行规则:
- 同一时刻只允许一个升级任务处于 `RUNNING`
- 不允许目标版本低于当前版本
- 不满足最小兼容版本时拒绝升级
- `execute.sh` 必填,`precheck.sh`、`verify.sh`、`rollback.sh` 可选
- 执行顺序为:`precheck -> execute -> verify`
- `TMS` 自升级包内脚本第一版不应直接 `stop/start` 当前 TMS推荐只完成文件准备由后端在写入终态和日志后异步触发 `/home/tms/scripts/tms.sh restart`
- `FIRMWARE` 不增加额外后端流程,具体固件刷写、重启、恢复提示由包内脚本负责
- 回滚不自动触发,需要调用回滚接口
- `TMS`、`RECEIVER` 升级成功后会更新 `tms_device_software_version``FIRMWARE` 暂不维护版本表
## Resource Backup / Restore
最小调用顺序:
- `POST /api/v1/resource-backups`
- `GET /api/v1/resource-backups/{taskId}`
- `GET /api/v1/resource-backups/{taskId}/download`
- `POST /api/v1/resource-restores/precheck`
- `POST /api/v1/resource-restores`
- `POST /api/v1/resource-restores/{taskId}/apply`
- `GET /api/v1/resource-restores/latest`
恢复任务创建接口只完成验签、解密、展开和计划生成;前端只做一次“确认恢复”,确认后先调用创建接口,返回 `READY_TO_APPLY` 后立即调用 apply 接口进入停机恢复。也就是用户确认后调用 apply 接口进入停机恢复不再做第二次确认。TMS 重启后前端可调用 latest 接口展示最近一次恢复时间、结果和失败原因。
前后端字段、状态枚举和联调流程见 `docs/openapi/resource-backup-restore-frontend-integration.md`
当前实现边界:
- 资源备份包输出为 `.tmsbak`,包内包含 `manifest.json`、`envelope.json`、`payload.enc`、`signature.sig`
- `payload.enc` 加解密使用 PCIe 密码卡 SDF 会话密钥流程:备份时通过 `SDF_GenerateKeyWithIPK_ECC` 生成内部 ECC 公钥包裹的会话密钥并用 `SDF_Encrypt` 加密 payload恢复时通过 `SDF_ImportKeyWithISK_ECC` 导入包裹会话密钥并用 `SDF_Decrypt` 解密 payload。`envelope.json` 保持 `version=1`,只记录 `payloadAlg`、`ivBase64` 和 `wrappedSessionKeyBase64``keyIndex/keyBits/algId` 由系统固定约定。
- 当前第一版备份/恢复只覆盖最小资源集:
- `TMS_CONFIG`
- `TMS_DB`
- `CMEP_DB`
- `ORG_DB`(标准/间参收发器以 `orgCode` 命名的机构业务库;`DIRECT` 模式不包含)
- `CP_CONFIG`
- `RECEIVER_LICENSE`
- `STANDARD_CMSP_APP_CONFIG`(标准版 CMSP 应用配置,由默认 `tms.backup.file-resources` 配置匹配 `/home/cmep4i/cmsp/application-prd*.properties`
- `STANDARD_CMTP_APP_CONFIG`(标准版 CMTP 应用配置,由默认 `tms.backup.file-resources` 配置匹配 `/home/cmep4i/cmtp/application-prd*.properties`
- `USER_KEY`(从实体证书 `KeyEntity.keyIdx` 采集用户密钥备份)
- `MQ_REPLAY`
- 预检阶段只做包头解析、指纹匹配和验签,不提前解密完整 payload
- 恢复任务创建时 Java 完成验签、PCIe/SDF 解密、payload 展开、用户密钥恢复和恢复路径白名单校验
- Java 会生成 shell 友好的 `restore-files.tsv`、`restore-databases.tsv`、`restore-mq.tsv`
- 创建恢复任务后启动 `apply-resource-backup.sh --work-dir <workDir>`,由 shell 执行停服务、文件覆盖、SQL 导入、MQ replay、起服务和健康检查
- Java 启动恢复脚本前会在工作目录生成 `restore-env.sh`、`restore-stop-commands.tsv`、`restore-start-commands.tsv`;停启服务命令来自 `tms.backup.restore-stop-commands` / `tms.backup.restore-start-commands`
- 标准/间参默认恢复后会启动 TMS、CMSP/CMTP 和 nginx现场需要启动其它软件时只需在上述命令列表里增删配置项
- shell 侧状态写入 `status.json`,日志写入 `restore.log`
- 第一版资源恢复是停机恢复。创建恢复任务后当前TMS服务可能中断前端应提示用户恢复期间页面/API可能不可用恢复结果以后续健康检查、重新登录和 `status.json` / `restore.log` 为准。
- `FILE` 回写 manifest 明确声明的配置/License 文件
- 可通过 `tms.backup.file-resources` 自行增删直接复制恢复的文件类资源:
- `mode=FILE`:单文件,`restore-path` 是目标文件路径
- `mode=DIR`:目录递归,`restore-path` 是目标目录
- `mode=GLOB`:通配符匹配同一目录下的一批文件,`restore-path` 是目标目录
- `product-types` / `mq-types`:可选过滤条件;不配置表示所有产品类型或 MQ 类型都适用
- `required=true` 时匹配不到或读取失败会导致备份失败,`required=false` 时跳过并写入 manifest
- `DATABASE` 恢复:
- `db/TMS.sql`
- `db/CMEP.sql`(包内存在时)
- `db/<orgCode>.sql`(标准/间参收发器包内存在时,导回同名机构库)
- `TMS_DB` 备份默认通过 `tms.backup.tms-db-excluded-tables` 排除角色、授权、会话和资源备份/恢复任务表,恢复时不会覆盖新机器安全登录状态,也不会把旧的 `RUNNING` 任务带到新机器;`tms_operation_audit_log` 默认随 TMS 库一起备份
- `MQ_REPLAY` 通过 `replay-mq.sh` 消费 `mq/mq-restore-context.json`,也可用 `MQ_REPLAY_COMMAND` 委派给现场脚本
- Java 启动恢复脚本前会在工作目录生成 `restore-env.sh`传递数据库连接、恢复脚本路径、MQ replay 脚本路径和健康检查配置;健康检查会按配置重试等待 TMS 真正启动完成
关键配置:
- `tms.backup.output-dir`
- `tms.backup.precheck-store-dir`
- `tms.backup.restore-task-root-dir`
- `tms.backup.tms-script-path`
- `tms.backup.restore-stop-commands`
- `tms.backup.restore-start-commands`
- `tms.backup.restore-apply-script-path`
- `tms.backup.allowed-restore-roots`
- `tms.backup.file-resources`
- `tms.backup.mysqldump-path`
- `tms.backup.mysqldump-timeout-seconds`
- `tms.backup.mysql-path`
- `tms.backup.restore-db-script-path`
- `tms.backup.restore-db-timeout-seconds`
- `tms.backup.mq-replay-script-path`
- `tms.backup.tms-database-name`
- `tms.backup.tms-db-excluded-tables`
- `tms.backup.cmep-database-name`
- `tms.backup.health-check-url`
- `tms.backup.health-check-timeout-seconds`
- `tms.backup.health-check-max-wait-seconds`
- `tms.backup.health-check-retry-interval-seconds`
恢复前置条件:
- LMK、IK、数据存储加密密钥对、数据真实性保护密钥对需先通过 UKey 恢复
- `/home/tms/bin/resource-restore/apply-resource-backup.sh`、`restore-db.sh`、`replay-mq.sh` 必须已部署并可执行
- `mysql` / `mysqldump` 客户端必须可用
当前明确不在第一版恢复范围内:
- nginx 配置
- `organization.json`
- 已发布 web 静态资源
- `/home/tms/uploads`
- 机构库
- 在线恢复 / 增量恢复 / 回滚
- 升级执行日志统一写入 `tms.upgrade.log-dir`
联调清单:
- [资源备份恢复 V1 联调清单](/Users/waner/Work/CISD/文档/tms-framework/docs/plans/2026-04-18-resource-backup-restore-v1-checklist.md)
当前配置项:
- `tms.upgrade.staging-root-dir`
- `tms.upgrade.log-dir`
- `tms.upgrade.signature-public-key-pem-path`
升级包规范见:
- [2026-03-19-upgrade-package-spec.md](/Users/waner/Work/CISD/文档/tms-framework/docs/plans/2026-03-19-upgrade-package-spec.md)
- [标准收发器升级包最小样例](/Users/waner/Work/CISD/文档/tms-framework/docs/examples/upgrade-package/standard-app/README.md)
- [离线升级包预检联调清单与示例](/Users/waner/Work/CISD/文档/tms-framework/docs/plans/2026-03-19-upgrade-preview-integration-guide.md)
## Architecture (Monolith + Modular)
- One deployable Spring Boot application.
- Module-first packaging under `modules/*`.
- Default module layout: `controller + service + repository + entity + dto`.
- `sign` module has extra `controller/openapi`, `dto/openapi`, and `support`.
- Cross-cutting concerns moved to top-level `security` and `integration`.
## Project Structure
```text
src/main/java/com/cisd/tms
├── TmsApplication.java
├── common
│ ├── api
│ ├── config
│ │ └── properties
│ ├── constant
│ ├── enums
│ ├── exception
│ └── util
├── infrastructure
│ └── persistence
│ ├── entity
│ ├── mapper
│ └── mybatis
├── integration
│ ├── cips
│ ├── mq
│ ├── crypto
│ └── file
├── security
│ ├── internal
│ └── openapi
└── modules
├── system
│ ├── controller
│ ├── service
│ └── dto
├── sign
│ ├── controller
│ ├── controller/openapi
│ ├── service
│ ├── dto/internal
│ ├── dto/openapi
│ ├── support
│ ├── repository
│ └── entity
├── init
├── auth
## Auth Compat
当前仓库只包含后端认证接口,不包含登录页前端工程。
兼容旧管理端的登录调用说明见:
- [2026-03-23-auth-compat-integration-guide.md](/Users/waner/Work/CISD/文档/tms-framework/docs/plans/2026-03-23-auth-compat-integration-guide.md)
├── device
├── upgrade
├── cert
├── key
├── audit
├── backup
└── activation
```
```text
src/main/resources
├── application.yml
├── application-dev.yml
├── application-prod.yml
├── mapper
│ ├── init/InitTaskMapper.xml
│ ├── auth/AuthUserMapper.xml
│ └── device/DeviceNodeMapper.xml
└── db/migration
└── V1__init_auth_device_tables.sql
```
## API Boundary Rules
- `/api/**` controllers live under `controller`.
- External API controllers only in `*/controller/openapi`, path prefix `/openapi/**`.
- Internal and external DTOs are separated.
- Cross-module calls must go through `service`, not `repository`.
- Internal token interceptor exclusions: `/api/v1/device/status`, `/api/v1/auth/login`.
## Auth Configuration
```yaml
tms:
security:
internal-token: ${TMS_INTERNAL_TOKEN:change-me-internal-token}
openapi:
timestamp-skew-seconds: 300
clients:
demo-app: ${TMS_OPENAPI_DEMO_SECRET:change-me-openapi-secret}
```
## Crypto Card Configuration
```yaml
tms:
crypto-card:
enabled: ${TMS_CRYPTO_CARD_ENABLED:false}
mode: ${TMS_CRYPTO_CARD_MODE:MOCK} # MOCK / JNA
vendor-lib-path: ${TMS_CRYPTO_VENDOR_LIB_PATH:/home/tms/libs/libsdf_ukey_syd1408-x64.so.1.0.0}
vendor-lib-name: ${TMS_CRYPTO_VENDOR_LIB_NAME:sdf_ukey_syd1408}
```
- Internal PCIe debug APIs (strong-typed service):
- `GET /api/v1/device/crypto/device-count`
- `GET /api/v1/device/crypto/device-conf`
- `GET /api/v1/device/crypto/device-info`
- `GET /api/v1/device/crypto/random?length=16`
- `POST /api/v1/device/crypto/self-test`
- `POST /api/v1/device/crypto/hmac`
- `POST /api/v1/device/crypto/digest`
- `POST /api/v1/device/crypto/encrypt/plain`
- `POST /api/v1/device/crypto/decrypt/plain`
- `POST /api/v1/device/crypto/encrypt/kek`
- `POST /api/v1/device/crypto/decrypt/kek`
- `POST /api/v1/device/crypto/mac/plain`
- `POST /api/v1/device/crypto/file/create`
- `POST /api/v1/device/crypto/file/write`
- `POST /api/v1/device/crypto/file/read`
- `POST /api/v1/device/crypto/file/delete`
- `POST /api/v1/device/crypto/kek/generate`
- `GET /api/v1/device/crypto/kek/status?keyIndex=1`
- `GET /api/v1/device/crypto/lmk/seed-mac`
- `POST /api/v1/device/crypto/std/keypair/rsa`
- `POST /api/v1/device/crypto/std/keypair/ecc`
- `POST /api/v1/device/crypto/envelope/exchange/rsa`
- `POST /api/v1/device/crypto/envelope/exchange/ecc`
- `POST /api/v1/device/crypto/agreement/data-key/ecc`
- `POST /api/v1/device/crypto/agreement/session-key/ecc`
## PCIe Crypto Unified Wrapper (JNA)
The project keeps JNA native mappings for PCIe card `SDF/SDFE` interfaces from
`PCIE密码卡应用接口说明书 V1.02`, and provides strong-typed service APIs via
`com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService`.
```yaml
tms:
crypto-card:
enabled: ${TMS_CRYPTO_CARD_ENABLED:false}
mode: ${TMS_CRYPTO_CARD_MODE:JNA} # MOCK / JNA
vendor-lib-path: ${TMS_CRYPTO_VENDOR_LIB_PATH:/home/tms/libs/libsdf_ukey_syd1408-x64.so.1.0.0}
vendor-lib-name: ${TMS_CRYPTO_VENDOR_LIB_NAME:sdf_ukey_syd1408}
```
- JNA native mapping: `com.cisd.tms.integration.crypto.pcie.jna.PcieNativeLibrary`
- JNA implementation: `com.cisd.tms.integration.crypto.pcie.service.JnaPcieCryptoService`
- Mock fallback: `com.cisd.tms.integration.crypto.pcie.service.MockPcieCryptoService`
### OpenAPI Signature Rules
- Headers: `X-App-Id`, `X-Timestamp`, `X-Nonce`, `X-Signature`
- Canonical string: `appId + "\\n" + timestamp + "\\n" + nonce`
- Signature algorithm: `HMAC-SHA256` with app secret, lowercase hex
- Replay protection: nonce one-time in time window
## Build And Test
```bash
mvn -q -DskipTests compile
mvn -q test
```
## PCIe Real-Card Smoke
- Checklist: `docs/plans/2026-02-28-pcie-realcard-smoke-checklist.md`
- Script template: `scripts/pcie_realcard_smoke.sh`
Example:
```bash
export BASE_URL=http://127.0.0.1:8080
export INTERNAL_TOKEN=change-me-internal-token
export ALG_SM3=1
export ALG_SM4_ECB=1025
./scripts/pcie_realcard_smoke.sh
```
- CI is pinned to JDK 17 via `.github/workflows/ci.yml`.
- Maven Surefire preloads Mockito javaagent to avoid dynamic self-attach failures on newer JDKs.
## Current Status
- Structure refactored to lightweight monolith modules.
- Internal and external API entry points separated.
- Basic auth interceptors for internal/openapi are in place.
- `init/auth/device/sign/system` modules have runnable skeleton controllers and services.
- `init/auth/device` modules include mapper+xml+repository-impl+DDL skeleton for TiDB.