# 安全设计能力差距整改方案 > 对照基准:`docs/方案计划文档管理系统技术方案.md` 第 5 章(安全保密措施设计)、6.5(安全性设计)、 > `docs/方案计划文档管理系统技术方案-补充修改说明.md`(三权分立、四层授权模型、门户对接认证、5.7 开发过程安全保密)。 > 验证范围:Python 版(backend/)、Java 版(backend-java/src/)、前端(frontend/src/),双后端逐条对齐核验。 > 对照日期:2026-09-07。总体结论:34 项安全设计要求中具备 20 项、部分具备 7 项、不具备 7 项。 ## 1. 差距清单 ### 1.1 高优先级(纵深防御核心缺口) | 编号 | 差距项 | 现状证据 | 整改方向 | |---|---|---|---| | G-01 | 传输加密(HTTPS)不具备 | 双版无 ssl 配置;`app.run(debug=False)` 无 ssl_context;JDBC 串显式 `useSSL=false` | 部署层引入部署单位签发证书/反向代理终止 TLS;数据库连接串按部署单位密码设施开启加密通道 | | G-02 | 应用层信封加密 KEK/DEK 不具备 | 文件流式明文直写(`uploads.py:150-156`、`UploadStorage.java:124-126`);无字段级加密、无密钥轮换 | **本轮实施**(见 2.2) | | G-03 | 审计哈希链防篡改不具备 | 审计表无 prev_hash/record_hash 字段,写入纯 INSERT 直插,事后篡改无法被校验发现 | 迁移加列(prev_hash/record_hash)+ 写入时计算内容哈希并纳入前条摘要 + 审计链连续性校验接口 + 审计动作白名单扩充(需 Alembic/Flyway 双引擎迁移与 CHECK 白名单更新) | | G-04 | 敏感操作二次认证不具备 | 全库无操作人登录密码复核机制(现有"文档密码锁"为资源级口令,性质不同) | **本轮实施**(见 2.3) | ### 1.2 中优先级 | 编号 | 差距项 | 现状证据 | 整改方向 | |---|---|---|---| | G-05 | 自动化备份机制不具备 | 无全量/增量备份脚本、无只追加不覆盖备份目录,仅 README 手工 mysqldump 建议 | 备份执行脚本(周全量/日增量)+ 备份目录只追加 + 保留策略与校验 | | G-06 | 三权分立角色体系不具备 | 角色仅 USER/ADMIN 两档(历史 AUDITOR 已于迁移 0003 禁用);审计查询权归全体 ADMIN,未与系统管理员分离 | 需契约级设计:新增安全管理员/安全审计员角色、审计权独立、管理范围细化 | | G-07 | 权限申请审批流不具备 | 无申请单表/接口/界面/审计动作;借阅"审批单凭证"为事后留痕,无事前申请—审批链 | 需契约级设计:申请单模型、待办流转、批准即生成借阅授权、全程审计 | ### 1.3 低优先级 / 覆盖面补全 | 编号 | 差距项 | 现状证据 | 整改方向 | |---|---|---|---| | G-08 | JWT 有效期硬编码 2 小时(设计 1 小时) | `config.py:135`、`JwtTokens.java:29`(7200s 硬编码) | **本轮顺带实施**(见 2.1) | | G-09 | 审计导出电子表格缺失 | 双端无 audit/export/xlsx/csv 接口 | 审计看板新增导出接口(xlsx) | | G-10 | 原始文件未按"业务类型、年月"分层 | `original/{uuid}.{ext}` 扁平结构 | 存储路径分层 + 存量文件迁移(可选) | | G-11 | LibreOffice 转换进程无内存上限 | 双端仅有 60s 超时 + 信号量限流(默认 2),无进程内存限制 | 启动器/容器层 ulimit 或 Job Object 内存上限 | | G-12 | IP 登录限制仅部门维度、ADMIN 全量豁免 | `ip_entry_service.py:391-421`、`LoginIpService.java:24-61` | 评估是否增加按用户维度条目与 ADMIN 收敛 | | G-13 | Java 版全局安全响应头仅在送检副本 | `SecurityHeadersFilter.java`(X-Frame-Options/CSP/Referrer-Policy/Cache-Control)只存在于 backend-java/src-check,运行源码 backend-java/src 无此文件,Python 版亦无对应中间件 | 将该过滤器同步至 backend-java/src,Python 版补等价中间件 | | G-14 | LibreOfficeConverter 调试日志残留 | `LibreOfficeConverter.java:245,262` 以 info 级打印完整命令行 | 降级为 debug 或删除 | | G-15 | 信封加密覆盖面补全(本轮之后) | 本轮仅覆盖 original/ 原始文件;preview/、extracted/ 目录仍为明文缓存;数据库敏感字段未加密;无密钥轮换;存量明文文件未迁移 | preview/extracted 缓存加密、审计备注等字段级 DEK、KEK 轮换命令(kekVersion 已预留)、存量明文迁移 CLI | 说明:文档级 ACL 组织授权与多操作位下线(迁移 0026/V11 借阅制收敛)、部门范围 OWN/OTHER 收敛,属既有契约有意演进,不计入差距。 ## 2. 本轮实施范围(批次一) ### 2.1 访问令牌有效期默认 1 小时并配置化 - 配置键 `DMS_JWT_EXPIRES_SECONDS`(环境变量/.env,双版同名对齐),缺省 3600。 - Python `backend/dms/config.py` 由硬编码 7200 改为环境变量读取;Java `JwtTokens` 由静态常量改为随环境变量解析。 - `.env.example` 增加该项及生成说明。 ### 2.2 应用层信封加密(原始文件 original/) - 算法与格式:AES-256-GCM;信封文件头 `DMSE` + kekVersion(1B) + DEK 包裹长度(4B) + KEK 包裹的 DEK + 数据密文;DEK 每文件随机 32B;GCM nonce 12B 随机。 - 主密钥:配置键 `DMS_STORAGE_KEK`(base64,32B),环境变量注入、不落盘;未配置时回退明文兼容模式(不加密,读取自动识别)。 - 写路径:上传暂存 promote 至 original/ 时加密落盘(新建与覆盖上传)。 - 读路径:下载、预览转换、正文提取、重新解析、凭证读取统一经解密入口——密文先解密至临时明文文件、使用后清理;无 `DMSE` 头的存量明文文件按明文直接读取(无需迁移)。 - 覆盖面边界:preview/、extracted/ 缓存目录与数据库字段加密、密钥轮换、存量迁移列入 G-15 后续批次。 ### 2.3 敏感操作二次认证(操作人重输登录密码) - 新增 `POST /auth/reauth`:登录态提交 `{password}`,后端 Argon2id 校验通过后签发 5 分钟 reauth 令牌(JWT,type=reauth,绑定 userId 与 authVersion——重置密码/角色变更后自动失效)。 - 敏感接口校验请求头 `X-DMS-Reauth-Token`:验签、type、userId、authVersion、有效期;缺失或无效返回 403 `REAUTH_REQUIRED`(附"请重新输入登录密码"语义)。 - 覆盖操作(按设计条目映射到现有接口): - 用户密级/角色/状态变更:`PUT /users/{id}`(仅当 securityLevel、roleCode/roleId、status 实际发生变化时强制); - 权限批量授予与撤销:文档借阅授权保存与删除接口、角色权限矩阵保存接口。 - 文档销毁、备份恢复、主备切换:系统暂无对应功能,待功能引入时纳入。 - 前端:敏感操作确认时弹出登录密码对话框 → 调 reauth 接口换取令牌 → 自动携带请求头执行操作;令牌内存缓存 5 分钟内免重复输入;403 REAUTH_REQUIRED 自动重新弹窗。 - 契约:`DMS_API_CONTRACT.md` 升版(1.20 → 1.21),新增接口、请求头与错误码说明。 ## 3. 后续批次建议 - 批次二:G-03 审计哈希链、G-13 安全响应头同步、G-14 日志残留清理。 - 批次三:G-01 传输加密(部署侧配合)、G-05 自动化备份、G-15 信封加密覆盖面。 - 批次四:G-06 三权分立、G-07 权限申请审批流(涉及契约大版本升级与角色体系重构)。 - 择机:G-09 审计导出、G-10 存储分层、G-11 内存上限、G-12 IP 维度。 ## 4. 验证方案 - 单元测试:信封加解密 round-trip 与明文兼容、reauth 令牌签发/校验/失效(authVersion 变化)、JWT 有效期配置读取。 - 集成测试:未携带/携带无效 reauth 头的敏感操作返回 403;密文文件下载、预览转换、正文提取与重新解析全链路正常;KEK 未配置回退明文模式。 - 手动验证(用户执行):前端三处敏感操作弹窗链路、5 分钟免重复、令牌过期后重新弹窗。