上传文件至「docs/architecture」
This commit is contained in:
@@ -0,0 +1,396 @@
|
||||
# 滨化集团智慧招标平台(STP)数据安全机制设计
|
||||
|
||||
---
|
||||
|
||||
## 1. 总体安全策略与目标
|
||||
|
||||
为确保招标全流程数据的机密性、完整性和可用性,针对内外部威胁(包括具备服务器操作权限的开发人员、DBA、运维人员),建立 **“数据全程加密、密钥动态漂移、权限最小化、AI按需脱敏”** 的纵深防御体系。所有加密与密钥管理均在应用层和内存中实现。
|
||||
|
||||
**核心目标**:
|
||||
|
||||
- **防窥探**:即使攻击者获得服务器操作权限,也无法直接读取数据库中的招标敏感数据(如投标报价、专家打分、关联关系图谱)。
|
||||
- **防泄露**:静态文件加密存储,传输全程TLS 1.3加密,密钥在内存中动态漂移,杜绝落盘。
|
||||
- **防越权**:前后端双重权限校验,AI Agent仅能通过流程状态门控获取被授权数据,禁止通过对话方式旁路获取受限信息。
|
||||
- **可审计**:所有数据访问、密钥迁移、AI调用行为均记录不可篡改日志(使用哈希链+数字签名代替区块链)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 密钥管理机制:内存动态漂移 + 应用层分割
|
||||
|
||||
### 2.1 设计原则
|
||||
|
||||
- **密钥永不落盘**:加密密钥(数据密钥、文件密钥)仅在服务器内存中生成和存储,禁止写入任何持久化存储(磁盘、SSD、数据库)。
|
||||
- **动态漂移**:密钥的存储内存地址每隔若干小时随机迁移,同时变更密钥本身(旧密文使用旧密钥解密后使用新密钥重加密),降低内存被暴力扫描窃取的风险。
|
||||
- **密钥分割**:单条数据密钥被分割为2~3个分片,保存在不同进程/容器的内存区域,使用时分片聚合,用完即时销毁。
|
||||
|
||||
### 2.2 具体实现
|
||||
|
||||
| 组件 | 技术方案 |
|
||||
| :--------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **数据加密密钥 (DEK)** | 每条招标项目、投标文件、专家评分记录使用独立 DEK。DEK 由应用服务在内存中随机生成,永不落盘。DEK 的密文可存储于数据库,但主密钥仅在内存中。 |
|
||||
| **主密钥 (MEK)** | 每个微服务实例启动时,从配置中心读取一个种子口令,通过 PBKDF2 派生出一个 32 字节的主密钥,仅存于内存。该主密钥用于加密所有 DEK。主密钥不漂移,但服务重启时会重新派生。 |
|
||||
| **密钥分割** | 不使用复杂的秘密共享算法,简化实现:将 32 字节 DEK 切分为两段各 16 字节,分别存放于两个不同微服务容器的内存中。需要解密时,两个片段临时聚合,用完后立即清零。 |
|
||||
| **内存漂移调度器** | 独立微服务 `KeyDrifter`,每 4 小时(可配置)触发:<br>1. 扫描所有活跃 DEK 标识;<br>2. 生成新的随机内存地址(不同进程/堆区域),生成新 DEK;<br>3. 从旧地址读取旧 DEK,解密数据后用新 DEK 重加密,并将加密后 DEK 存回数据库;<br>4. 更新内存索引,清零旧内存区域。 |
|
||||
| **内存保护** | 使用 `mlock()` 系统调用锁定内存页,防止被 swap 到磁盘;使用 `mprotect()` 设置非执行权限;敏感内存区域使用 `zeroize` 库在释放前覆盖。 |
|
||||
|
||||
### 2.3 密钥生命周期
|
||||
|
||||
```
|
||||
[生成] 首次写入加密字段时,由应用服务生成 DEK(随机字节) → 分割为两片段 → 分片存入不同服务内存。
|
||||
[使用] 业务服务请求解密 → 聚合分片 → 解密后立即销毁聚合缓存。
|
||||
[漂移] KeyDrifter 锁住当前进程内存 → 新内存区生成新 DEK → 复制数据并重加密 → 更新数据库中的密文(DEK 仍使用同一个 MEK 加密存储) → 释放旧区。
|
||||
[销毁] 项目归档期满后,删除 DEK 内存引用,内存页清零,数据库中对应的加密 DEK 字段标记为已删除(但物理数据无法解密)。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 静态数据加密
|
||||
|
||||
### 3.1 数据库加密
|
||||
|
||||
| 加密粒度 | 实施方案 |
|
||||
| :-------- | :----------------------------------------------------------------------------------- |
|
||||
| **透明加密** | 使用磁盘加密作为基础防护,防止物理磁盘被盗。但透明加密不防止 DBA 直接读取数据库文件,因此仍需字段级加密。 |
|
||||
| **字段级加密** | 对极端敏感字段采用应用层字段加密:每个字段使用独立 DEK,DEK 密文存储在同一行的单独列中。加密算法:AES-256-GCM,附加认证数据(AAD)为表名+行ID。 |
|
||||
| **索引混淆** | 加密字段不能直接用于条件查询,采用确定性加密生成可搜索的盲索引,盐值也存在于内存中,定期轮换并重建索引。 |
|
||||
|
||||
### 3.2 静态文件加密
|
||||
|
||||
所有上传文件(投标书PDF、资质扫描件、专家承诺书、音视频记录)采用信封加密:
|
||||
|
||||
1. 每个文件随机生成文件密钥,内存中保存。
|
||||
2. 使用 FEK 对文件进行AES-256-GCM加密,分块上传(每块 4MB),每块独立加密。
|
||||
3. FEK 使用主密钥加密后,作为文件元数据的一部分存储于对象存储的 `metadata` 字段或单独数据库表。
|
||||
4. 文件在对象存储中始终处于密文状态,即使直接拷贝也无法读取。
|
||||
5. 文件访问时,应用服务器从内存中获取 MEK → 解密 FEK → 用 FEK 解密文件流 → 传输给授权前端,不落地。
|
||||
|
||||
### 3.3 备份与快照加密
|
||||
|
||||
- 数据库备份、对象存储快照必须使用独立的备份密码。
|
||||
- 备份密钥由双人控制(分段存储于两个保险柜),恢复时需要两人输入各自的密码段。
|
||||
|
||||
---
|
||||
|
||||
## 4. 传输加密与 API 安全
|
||||
|
||||
### 4.1 全链路 TLS 1.3
|
||||
|
||||
- 所有对外服务(前端、API、Webhook)强制启用 TLS 1.3,禁用弱密码套件。
|
||||
- 使用内部 CA 签发服务端证书,客户端验证服务端证书指纹。
|
||||
- 服务间调用(微服务、AI Agent)采用 mTLS,双向认证。
|
||||
|
||||
### 4.2 API 请求签名
|
||||
|
||||
- 对外 API(供应商、第三方系统)需使用 OAuth2.0 Client Credentials 获取 token,请求头携带 `Authorization: Bearer <jwt>`。
|
||||
- 对关键操作(上传投标、修改报价)额外要求 **请求签名**:`HMAC-SHA256(requestBody + timestamp + nonce, clientSecret)`,服务器校验签名及时间窗口(≤ 5 分钟)。
|
||||
|
||||
### 4.3 前端通信加密增强
|
||||
|
||||
- WebSocket 传输实时打分数据时,在 TLS 之上再次进行应用层非对称加密(使用服务器公钥加密 payload),即使 TLS 被中间人破解,也无法直接解析业务数据。
|
||||
|
||||
---
|
||||
|
||||
## 5. 前后端权限隔离与角色端口设计
|
||||
|
||||
### 5.1 角色与端口映射
|
||||
|
||||
平台为不同角色分配独立的访问端口(或子域名),并在网关层绑定最小权限策略:
|
||||
|
||||
### 5.2 前后端双重权限校验
|
||||
|
||||
- **前端**:登录后获取 JWT,JWT 中仅包含角色和用户 ID,不包含任何权限矩阵。前端根据角色代码展示不同菜单,但关键按钮(如“查看报价”)仍需要后端二次确认。
|
||||
- **后端**:每个 API 调用都会执行 **Policy Enforcement Point (PEP)**,根据用户 ID + 资源 ID 查询:
|
||||
- 用户是否属于该项目的相关角色(如:该专家是否被分配到该项目评委组)
|
||||
- 当前流程状态是否允许访问该资源(例如:开标前任何人不能查看报价文件)
|
||||
- 使用 **Casbin** 或 **OPA** 实现动态规则引擎,规则可热更新。
|
||||
|
||||
---
|
||||
|
||||
## 6. AI Agent 安全隔离与按需数据访问
|
||||
|
||||
### 6.1 角色独立 AI Agent 架构
|
||||
|
||||
每个角色(供应商、专家、招标专员、审批人、管理员)分别部署一个独立的 AI Agent 容器,使用不同的 API Key 和身份凭证。Agent 之间的内存和密钥完全隔离。
|
||||
|
||||
### 6.2 流程驱动的数据门控
|
||||
|
||||
Agent 在调用任何业务数据前,必须通过统一数据网关验证请求合法性。网关检查:
|
||||
|
||||
1. **角色匹配**:Agent 的 JWT 中角色声明是否与目标数据要求一致。
|
||||
2. **流程状态**:查询招标项目的工作流引擎当前状态,根据前述“状态门控”决定是否放行。
|
||||
3. **数据脱敏**:即使允许访问,返回的数据也会根据角色自动脱敏(如专家 Agent 只能看到技术标中隐去供应商名称的版本)。
|
||||
|
||||
**调用时序示例**(专家 Agent 获取技术标):
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant ExpertAgent
|
||||
participant DataGateway
|
||||
participant WorkflowEngine
|
||||
participant FileService
|
||||
|
||||
ExpertAgent->>DataGateway: GET /tender/T001/tech_bid?projectId=...
|
||||
DataGateway->>WorkflowEngine: query project stage
|
||||
WorkflowEngine-->>DataGateway: stage = "evaluating"
|
||||
DataGateway->>DataGateway: 校验专家是否属于该项目评委组(内存中缓存)
|
||||
DataGateway->>FileService: 获取加密文件流
|
||||
FileService-->>DataGateway: 密文流 + 解密用 FEK(内存获取)
|
||||
DataGateway->>DataGateway: 解密 -> 移除供应商名称、Logo(NLP 脱敏)
|
||||
DataGateway-->>ExpertAgent: 脱敏后的技术标
|
||||
```
|
||||
|
||||
### 6.3 AI 对话隔离:防止越狱查询
|
||||
|
||||
当流程状态为“数据不可见”时,AI Agent 进入教学/流程提醒模式:
|
||||
|
||||
- Agent 的上下文(system prompt)强制注入:`当前阶段禁止透露任何项目数据,包括报价、投标人名称、评分。若用户询问数据,统一回答:“暂未到查看时间,请等待系统通知。如需帮助,请描述您的问题(如:如何上传文件?)”。`
|
||||
- 后端增加对话内容审计:每次用户询问,AI Agent 先将问题发送至越狱检测服务(基于语义相似度和正则),命中敏感词(“报价”、“分数”、“谁中标了”)且当前流程禁止时,直接拦截并记录异常日志。
|
||||
- 对于普通操作教学(“如何修改密码”),使用独立的“小滨-助手”知识库(不含任何项目数据),不涉及数据查询。
|
||||
|
||||
**架构示意**:
|
||||
|
||||
```
|
||||
用户对话 → API网关 → 角色Agent → [对话安全过滤器] → 若允许,则查询数据网关;否则,仅调用公共知识库RAG。
|
||||
```
|
||||
|
||||
### 6.4 Agent 调用审计
|
||||
|
||||
- 记录每个 Agent 发起的每一次数据请求(包括时间、项目ID、请求参数、返回数据指纹)。
|
||||
- 审计日志写入哈希链日志表,防止管理员篡改。
|
||||
|
||||
---
|
||||
|
||||
## 7. 防开发人员/DBA 窥探的硬性措施
|
||||
|
||||
即使开发人员拥有服务器 root 权限或数据库管理员权限,也无法直接读取明文敏感数据。
|
||||
|
||||
### 7.1 数据库层面
|
||||
|
||||
- **应用层加密**:数据库管理员看到的 `price_enc` 字段是 Base64 乱码,没有内存中的 DEK 无法解密。
|
||||
- **数据库连接账户隔离**:DBA 使用的 `root` 账户无法访问应用表(通过数据库行级安全策略 RLS 禁止),应用使用单独的 `app_user` 账户,该账户密码存放在配置中心(如 Vault),开发人员无法直接获取。
|
||||
- **查询审计**:数据库审计插件记录所有 `SELECT` 操作,若发现 DBA 批量查询加密字段,自动告警并冻结账户。
|
||||
|
||||
### 7.2 服务器与内存
|
||||
|
||||
- **禁止交互式 shell**:生产服务器禁止开发人员直接 SSH 登录,所有操作必须通过堡垒机 + 动态令牌,且操作全程录像。
|
||||
- **内核安全模块**:使用 SELinux/AppArmor 限制只有 `stp-app` 进程可读取 `/proc/self/mem` 中特定内存区域,其他进程(包括开发人员启动的调试器)无权限。
|
||||
- **内存转储禁止**:内核参数设置 `vm.dumpable = 0`,防止 `ptrace` 或 `gcore` 导出内存内容。
|
||||
- **动态漂移**:密钥每 4 小时迁移到不同进程内存,攻击者即使获得了某一时刻的内存快照,也只能看到已失效的密钥或分片。
|
||||
|
||||
### 7.3 开发与调试环境
|
||||
|
||||
- **脱敏数据镜像**:开发测试环境使用完全脱敏的伪造数据(通过数据脱敏工具生成),不包含真实供应商、报价。
|
||||
- **密钥沙盒**:开发环境使用独立的种子口令,无法接触生产密钥。
|
||||
- **CI/CD 隔离**:构建流水线中使用的变量(如数据库密码)来自 Vault 动态 secret,构建完成后立即失效。
|
||||
|
||||
---
|
||||
|
||||
## 8. 审计与监控(无区块链,改用哈希链)
|
||||
|
||||
### 8.1 审计日志保护(哈希链 + 数字签名)
|
||||
|
||||
不使用区块链,而是采用 **哈希链 + 数字签名** 保证日志不可篡改:
|
||||
|
||||
- 每条审计日志记录包含:`id`、`时间`、`操作者`、`操作内容`、`数据指纹`。
|
||||
- 每条日志的 `prev_hash` 字段指向前一条日志的哈希。
|
||||
- 每小时,系统对当前哈希链的最新哈希值,使用审计专用私钥进行签名,并将签名值保存到外部(如另一个数据库表或文件)。
|
||||
- 验证时,重新计算哈希链,比对签名。
|
||||
|
||||
### 8.2 审计内容范围
|
||||
|
||||
| 审计对象 | 采集内容 | 保留期限 | 存储方式 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| 用户访问日志 | 谁、何时、从哪个 IP、访问了哪个 API、返回了哪类数据(脱敏后指纹) | 7 年 | 哈希链日志表 + 离线归档 |
|
||||
| 密钥操作日志 | 密钥生成时间、漂移时间、销毁时间、涉及的内存地址范围(经过哈希) | 3 年 | 加密存储,仅合规人员可读 |
|
||||
| AI Agent 调用日志 | Agent 角色、请求参数、是否被拦截、越狱检测结果 | 3 年 | 同上 |
|
||||
| 数据库 DDL/DML | 所有 `INSERT/UPDATE/SELECT` 敏感表记录 | 永久 | 同步至独立 SIEM |
|
||||
| 异常告警 | 单用户异常访问、密钥漂移失败次数 | 实时推送 | 飞书/短信通知安全运维 |
|
||||
|
||||
---
|
||||
|
||||
## 9. 存证功能
|
||||
|
||||
### 9.1 存证目标与原则
|
||||
|
||||
- **独立存证表**:存证记录独立于业务数据库,使用哈希链防止篡改。
|
||||
- **可信时间戳**:对关键存证事件,调用第三方可信时间戳服务赋予法律效力。
|
||||
- **与加密机制协同**:存证哈希基于解密后的明文(但只传哈希,不传明文)。
|
||||
|
||||
### 9.2 存证范围与触发事件
|
||||
|
||||
| 阶段 | 存证事件 | 存证内容(哈希对象) | 触发时机 |
|
||||
| :------- | :-------- | :---------------- | :----------- |
|
||||
| **委托** | 招标委托单提交审批 | 委托单全文JSON | 用户点击“发起审批” |
|
||||
| | 委托审批通过 | 审批记录+签字意见 | OA回调“审批完成” |
|
||||
| **立项** | 招标方案确认 | 招标方案PDF | 立项审批通过 |
|
||||
| | 供应商短名单确认 | 短名单(供应商ID+推荐理由) | 短名单审批完成 |
|
||||
| **文件编制** | 招标文件定稿 | 招标文件PDF | 文件加密发布前 |
|
||||
| | 澄清/修改公告 | 澄清文件PDF | 发布前 |
|
||||
| **投标** | 投标文件上传完成 | 投标文件哈希+上传时间戳 | 供应商上传加密文件成功后 |
|
||||
| | 保证金缴纳凭证 | 银行回单PDF | 支付网关回调成功 |
|
||||
| **开标** | 开标记录 | 开标现场音视频文件哈希+关键截屏 | 开标结束时 |
|
||||
| **评标** | 评委打分 | 每个评委的评分表(含打分项) | 评委提交评分 |
|
||||
| | 偏离度复核记录 | AI提醒+评委确认意见 | 评委复核确认 |
|
||||
| **定标** | 评标报告 | 评标报告PDF | 报告定稿 |
|
||||
| | 中标结果审批 | 定标审批单+领导签字 | 定标审批通过 |
|
||||
| **合同** | 合同签订 | 电子合同PDF | 双方电子签章完成 |
|
||||
| **归档** | 全项目归档包 | 所有存证哈希组成的Merkle树根 | 归档完成时 |
|
||||
|
||||
### 9.3 存证技术方案
|
||||
|
||||
| 层级 | 技术 | 用途 | 成本 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **第一层:内部哈希链** | SHA-256 + 前后哈希引用 | 内部防止日志篡改,快速验证,无需外部依赖 | 无 |
|
||||
| **第二层:可信时间戳** | 联合信任时间戳、腾讯云时间戳等 | 赋予法律效力,诉讼时可出证 | 按次收费,约1-5元/次(仅重大项目调用) |
|
||||
|
||||
### 9.4 存证数据结构
|
||||
|
||||
```json
|
||||
{
|
||||
"evidence_id": "E_20260602_001",
|
||||
"project_id": "T2026001",
|
||||
"event_type": "bid_submit",
|
||||
"event_time": "2026-06-02T10:30:00Z",
|
||||
"content_hash": "sha256:7b3d...f2a1",
|
||||
"content_meta": {
|
||||
"file_name": "技术标.pdf",
|
||||
"file_size": 2048576,
|
||||
"original_storage_path": "encrypted://minio/bucket/..."
|
||||
},
|
||||
"signature": {
|
||||
"signer": "system_evidence",
|
||||
"signature_value": "base64..."
|
||||
},
|
||||
"prev_evidence_hash": "E_20260601_099_hash",
|
||||
"cur_hash": "sha256:...",
|
||||
"timestamp_proof": "https://timestamp.com/verify?hash=..." // 可选,仅重大项目
|
||||
}
|
||||
```
|
||||
|
||||
### 9.5 存证流程(以投标文件上传为例)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Supplier
|
||||
participant STP_App
|
||||
participant Encryptor
|
||||
participant Evidence_Service
|
||||
participant TimeStamp_API
|
||||
|
||||
Supplier->>STP_App: 上传加密投标文件
|
||||
STP_App->>Encryptor: 获取文件明文(临时解密)
|
||||
Encryptor-->>STP_App: 明文流
|
||||
STP_App->>STP_App: 计算 SHA-256(明文)
|
||||
STP_App->>Encryptor: 销毁明文流
|
||||
STP_App->>Evidence_Service: 发送存证请求(含哈希、项目ID、事件类型)
|
||||
Evidence_Service->>Evidence_Service: 计算当前哈希链
|
||||
Evidence_Service->>Evidence_Service: 签名(使用存证专用私钥)
|
||||
Evidence_Service->>TimeStamp_API: 提交哈希值(仅关键事件)
|
||||
TimeStamp_API-->>Evidence_Service: 返回时间戳证明URL
|
||||
Evidence_Service->>STP_App: 存证完成,返回 evidence_id
|
||||
STP_App->>Supplier: 上传成功,存证ID已记录
|
||||
```
|
||||
|
||||
### 9.6 验证与司法出证
|
||||
|
||||
- **内部验证**:在平台“存证验证”页面输入项目号,系统重新计算当前数据哈希,与存证哈希比对,显示“通过”或“篡改”。
|
||||
- **司法出证**:管理员导出指定项目的完整存证包(含所有事件的哈希链、签名、时间戳证书),提交法院。法院可通过第三方时间戳官网核验。
|
||||
|
||||
---
|
||||
|
||||
## 10. 与现有加密方案的集成点
|
||||
|
||||
| 现有安全组件 | 存证集成方式 |
|
||||
| :---------------- | :----------------------------------------------- |
|
||||
| **内存密钥漂移** | 存证服务使用独立内存区域,不参与漂移。密钥仍由 MEK 保护,无KMS。 |
|
||||
| **字段级加密** | 存证时对**解密后的业务含义**(如报价金额数字)进行哈希,解密过程在安全沙箱中完成,用完即毁。 |
|
||||
| **文件加密存储** | 存证哈希基于文件**解密后内容**计算。验证时,先解密文件,再比对哈希。 |
|
||||
| **AI Agent 数据门控** | AI Agent 不能查询存证哈希值,只能由审计角色访问存证服务。 |
|
||||
| **前后端权限隔离** | 存证服务单独开放端口,仅审计角色和系统管理员可调用。 |
|
||||
|
||||
---
|
||||
|
||||
## 11. 应急响应与备份
|
||||
|
||||
### 11.1 密钥丢失恢复
|
||||
|
||||
主密钥(MEK)派生自种子口令。若所有服务内存崩溃导致 MEK 丢失:
|
||||
|
||||
- 使用离线备份的种子口令(分段保存在不同保险柜,需双人提供)重新派生 MEK。
|
||||
- 数据库中存储的 DEK 密文(用 MEK 加密)可以恢复,因为 MEK 不变(种子相同)。
|
||||
- 种子口令生成后,使用 Shamir 秘密共享分割为5份,交给5个不同负责人。恢复时需要至少3人提供片段。
|
||||
|
||||
### 11.2 数据备份
|
||||
|
||||
- 全量备份(加密)每天一次,保留30天。
|
||||
- 增量备份每6小时一次。
|
||||
- 备份密钥由种子口令派生,恢复时需双人授权。
|
||||
- 备份恢复演习每季度一次。
|
||||
|
||||
### 11.3 入侵响应
|
||||
|
||||
检测到内存扫描、暴力破解、异常数据导出行为 → 自动触发 **应急模式**:
|
||||
- 冻结当前所有用户会话
|
||||
- 强制销毁所有内存中的 DEK(触发全部数据锁定)
|
||||
- 通知安全团队介入
|
||||
|
||||
---
|
||||
|
||||
## 附录:加密机制全流程数据流示意图
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph Client
|
||||
A[前端/供应商]
|
||||
end
|
||||
|
||||
subgraph DMZ
|
||||
B[API网关<br>TLS + 签名验证]
|
||||
C[WAF]
|
||||
end
|
||||
|
||||
subgraph K8s集群
|
||||
subgraph UserService[用户服务]
|
||||
D[认证服务<br>颁发JWT]
|
||||
end
|
||||
subgraph BizService[业务微服务]
|
||||
E[招标服务]
|
||||
F[投标服务]
|
||||
G[评分服务]
|
||||
end
|
||||
subgraph KeyDrifter[KeyDrifter]
|
||||
H[密钥漂移器<br>内存管理]
|
||||
end
|
||||
subgraph AIAgents[AI Agents]
|
||||
I[独立角色Agent]
|
||||
J[越狱检测器]
|
||||
end
|
||||
subgraph DataLayer[Data Layer]
|
||||
K[(加密数据库<br>字段级密文)]
|
||||
L[(加密对象存储<br>MinIO)]
|
||||
end
|
||||
subgraph EvidenceLayer[存证层]
|
||||
M[存证服务]
|
||||
N[(哈希链日志表)]
|
||||
O[可信时间戳API<br>(可选)]
|
||||
end
|
||||
P[内存密钥池<br>(无KMS,应用管理)]
|
||||
end
|
||||
|
||||
A --> B --> C --> D
|
||||
C --> E
|
||||
E <--> P
|
||||
E --> K
|
||||
F --> L
|
||||
G --> P
|
||||
H --> P
|
||||
I --> J
|
||||
I --> E
|
||||
I --> G
|
||||
|
||||
E -.->|关键事件| M
|
||||
F -.->|投标文件| M
|
||||
G -.->|评分| M
|
||||
M --> N
|
||||
M -.-> O
|
||||
```
|
||||
Reference in New Issue
Block a user