Day37-19|18.5.5 完整性框架:保证数据没有被悄悄改变
Day37-19|18.5.5 完整性框架:保证数据没有被悄悄改变
对应教材目录:第 18 章 安全架构设计理论与实践 → 18.5 网络安全体系架构设计 → 18.5.5 完整性框架
学习目标:理解完整性与机密性、可用性、抗抵赖的区别;掌握传输、存储、业务、数据库和运维配置等不同层面的完整性保护;能够围绕校验、授权、版本、事务、审计和恢复写出完整案例答案。
一、完整性解决的是什么问题
完整性是指信息在存储、传输和处理过程中保持正确、完整、未被未经授权地修改。它不仅关心“数据有没有被攻击者改过”,也关心数据是否因为重复提交、并发覆盖、传输丢包、程序缺陷、配置误改或灾备恢复不完整而失真。
机密性回答“谁能看到”,完整性回答“内容是否可信”。一份文件即使只有授权用户能读取,如果其中金额被错误修改,仍然是不安全的;一条消息即使加密传输,如果攻击者可以重放旧消息让支付接口再次执行,也没有真正保证业务完整性。
完整性保护对象
|
+-- 内容完整:字节、字段、记录没有被非法改动
+-- 来源完整:数据确实来自声明的主体
+-- 顺序完整:消息没有丢失、插入、重复、重排
+-- 语义完整:业务状态转换符合规则
+-- 配置完整:关键配置没有被非法修改
+-- 审计完整:日志不能被删除或篡改
因此,高级系统架构设计师不能只写“使用哈希校验”。哈希可以发现内容变化,但不能单独证明是谁修改的,也不能阻止重放、越权写入和业务逻辑错误。
二、完整性框架的分层设计
完整性控制可拆为五层:
- 密码学完整性:摘要、消息认证码、数字签名和认证加密。
- 通信完整性:序列号、时间戳、随机数、重放检测、可靠传输和幂等。
- 数据完整性:约束、校验、事务、版本号、乐观锁和一致性校验。
- 业务完整性:状态机、金额规则、审批链、职责分离和防重复提交。
- 运营完整性:配置保护、发布审批、日志留存、备份校验和恢复演练。
输入数据
-> 身份认证与授权
-> 传输防篡改/防重放
-> 应用参数和业务规则校验
-> 事务与并发控制
-> 数据库约束与审计
-> 备份校验、监控和恢复
如果只依靠最底层密码学,而应用允许越权用户合法地修改数据,完整性仍然会被破坏;如果只依靠业务规则,而网络报文可以被重放或消息签名失效,同样会产生风险。
三、密码学完整性机制
1. 哈希摘要
哈希函数把任意长度的输入映射为固定长度摘要。接收方重新计算摘要,可以发现内容是否发生变化。它适合文件下载校验、备份校验、缓存校验和内容寻址,但公开摘要无法证明来源,因为攻击者可以同时替换内容和摘要。
2. 消息认证码
消息认证码使用共享密钥生成校验值,只有持有密钥的主体才能生成有效标签。它同时提供一定的来源认证和完整性保护,适合服务间高效通信。但共享密钥的分发和主体区分较困难,多个服务共享一把密钥时,难以判断究竟是谁生成了消息。
3. 数字签名
数字签名使用私钥签名、公钥验证,能够提供完整性、来源认证和一定程度的不可否认性。它适合合同、审批结果、软件包、配置发布和跨组织消息。架构设计时还要考虑证书链、吊销、时间戳、密钥保护和长期验证。
4. 认证加密
认证加密同时保护机密性和完整性,接收方必须先验证认证标签再解密和处理业务。这样可以避免应用在密文尚未验证时就使用部分明文。考试作答时应明确:认证加密可以组合两个目标,但仍不能代替授权、业务规则和幂等处理。
四、通信完整性与防重放
1. 为什么防篡改仍不够
攻击者不一定修改消息内容,也可能截获一条合法的“扣款”消息,然后在稍后重新发送。消息本身的签名仍然有效,但业务被重复执行。因此完整性设计必须把消息唯一标识、时间窗口、序列号、随机数和幂等键纳入考虑。
请求 = requestId + timestamp + nonce + sequence + body
签名 = Sign(privateKey, canonical(request))
服务端:验证签名 -> 检查时间窗 -> 检查 nonce/requestId
-> 检查序列号 -> 幂等判断 -> 执行业务
2. 消息规范化
签名双方必须对字段顺序、空值、数字格式、编码和时间格式达成一致,否则同一业务请求可能生成不同签名。应定义规范化规则,禁止把未参与签名的关键字段当作可信输入,防止“签了部分数据”的漏洞。
3. 可靠传输与顺序控制
支付、库存、订单和事件系统可能遇到丢失、重复、乱序。可以通过消息持久化、确认机制、重试、死信队列、顺序键和幂等消费者降低风险。但“至少一次投递”本身会产生重复消息,业务端必须把幂等处理设计出来。
五、数据库完整性设计
1. 实体完整性和参照完整性
主键保证记录可唯一识别,非空和唯一约束避免关键字段缺失和重复;外键或应用级参照规则保证关联记录有效。分布式数据库中即使不使用传统外键,也要通过服务约束、事件校验、定期对账和修复任务维护关系完整性。
2. 域完整性
字段类型、长度、枚举范围、金额精度和时间格式都应受到约束。不要把所有字段都定义为字符串再依赖前端校验,前端校验可以改善体验,但不能作为安全边界。
3. 事务与一致性
涉及账户余额、库存、订单状态和审批结果时,需要根据业务选择事务边界和一致性级别。单库交易可采用 ACID;跨服务业务可使用可靠事件、事务消息、补偿事务或工作流,并通过状态机限制非法状态跳转。
4. 并发控制
库存扣减和审批操作经常遇到并发更新。可以使用乐观锁版本号、数据库锁、条件更新、分布式锁或串行化队列。版本号设计示例:
UPDATE order
SET status = 'APPROVED', version = version + 1
WHERE id = ? AND status = 'PENDING' AND version = ?
影响行数为 0 时说明状态已变化或版本过期,服务应重新读取并返回明确结果,不能静默覆盖他人修改。
六、业务完整性:比数据库约束更接近风险
很多安全事故不是数据库被黑,而是合法接口被滥用。例如用户先提交订单,随后修改收货地址;审批完成后仍能修改金额;支付回调被重复处理;普通操作员可以直接把订单状态改为已付款。这些都属于业务完整性问题。
应使用显式状态机表达允许的状态转换:
草稿 --提交--> 待审批 --审批通过--> 待支付 --支付成功--> 已完成
| | |
撤回 驳回 超时取消
每个转换都应定义执行主体、前置条件、数据变更、幂等规则和审计事件。服务端不应接受任意 status 参数直接写库,而应根据当前状态和动作计算下一状态。
完整性还要求敏感业务采用职责分离。例如申请、审批、付款由不同角色执行;紧急操作需要双人复核;管理员修改规则要经过变更流程。授权合法不等于业务合理,完整性设计需要把流程和组织控制结合起来。
七、配置、软件包和日志完整性
1. 配置完整性
数据库连接、网关路由、权限规则、加密策略和安全组配置都可能影响系统安全。应使用配置中心、版本控制、审批发布、签名校验、变更审计和回滚机制。运行时配置要区分普通配置和安全配置,后者应限制修改人、窗口和范围。
2. 软件供应链完整性
部署包、容器镜像、依赖库和脚本应进行来源验证、摘要校验、签名验证和版本锁定。构建过程要保存构建记录和制品清单,避免“同一版本”实际内容不同。生产环境不应直接从不可信网络拉取未验证的程序包。
3. 日志完整性
日志可以记录安全事件,但日志本身也可能被攻击者删除或修改。可采用集中采集、只追加存储、访问隔离、哈希链、数字签名、远程写入和不可变对象存储。高价值日志应设置保留期限、时间同步和定期校验。
八、案例分析:支付订单系统的完整性架构
某支付订单系统包含下单、支付、退款和对账功能。要求防止订单金额被篡改,支付回调不能重复处理,退款必须经过授权,系统故障后能够与银行账单对账恢复。
可从以下方面设计:
- 订单金额、商户号、币种、订单号和回调地址纳入请求签名,服务端从可信订单重新计算金额,不信任客户端回传金额。
- 每次请求包含时间戳、随机数和唯一请求号,服务端保存短期 nonce 和幂等记录,拒绝过期和重复请求。
- 订单采用显式状态机,支付成功只能由受信任的支付渠道或对账任务推动,不能由普通前端接口直接写入。
- 支付回调先验签,再校验商户、订单、金额、币种和状态,最后在事务中更新状态并写入幂等结果。
- 退款采用最小权限和职责分离,超过金额阈值需要双人审批,退款操作不可超出原支付金额减去已退款金额。
- 采用数据库唯一约束、版本号和条件更新防止重复扣款和并发覆盖。
- 关键事件写入不可变审计日志,并将业务账、支付渠道账和银行账定期对账。
- 对账差异进入人工复核或补偿流程,不允许直接批量覆盖生产数据。
九、完整性与其他质量属性的权衡
强校验、同步事务和实时签名会增加延迟和计算成本;异步消息和最终一致性可以提高吞吐,但需要补偿、对账和异常处理;集中式密钥与签名服务有利于统一治理,却可能成为性能瓶颈。因此设计时要区分高价值操作和普通操作:支付、权限变更、配置发布、数据导出使用更强的校验;普通查询可以使用缓存和批量校验。
在案例答案中,最好明确验证指标:重复请求拦截率、签名失败告警时延、数据对账差异发现时延、恢复点目标、日志校验覆盖率和配置变更回滚时间。不要只写“提高了系统安全性”。
十、课后练习
练习 1
哈希摘要为什么不能单独证明数据来源?
参考答案:摘要通常可以公开计算,攻击者可以修改数据后重新计算摘要,因此它只能帮助发现变化,不能证明消息由可信主体生成。要证明来源,需要消息认证码或数字签名。
练习 2
支付回调已经使用数字签名,为什么仍需要幂等和防重放?
参考答案:签名只能证明消息在签署时来自可信方且内容未被修改,无法阻止同一条合法消息被重复发送。必须通过 requestId、时间戳、nonce、状态机和幂等记录防止重复执行。
练习 3
请设计一个配置发布的完整性保护流程。
参考答案要点:配置进入版本库;提交人和审批人分离;构建阶段生成摘要和签名;发布系统校验来源、版本和签名;目标环境采用最小权限账号;变更过程全量审计;发布后健康检查;出现异常可按版本回滚;关键配置禁止人工直接修改。
练习 4
论文题:论“高并发订单系统的完整性设计”。请至少从五个方面展开。
参考答案要点:请求签名和参数校验、时间戳与防重放、幂等键、状态机、事务和并发控制、数据库约束、消息可靠投递、职责分离、支付回调验签、对账补偿、审计日志和故障恢复。
十一、今日复盘
- 我能否区分哈希、消息认证码和数字签名的能力边界?
- 我是否同时考虑内容、来源、顺序、语义和日志完整性?
- 我能否解释重放攻击为何不是简单的篡改攻击?
- 我能否用状态机、幂等和版本号防止业务重复和并发覆盖?
- 我是否考虑了配置、软件包、备份和审计日志的完整性?
- 我能否在安全性与性能、可用性之间做出架构权衡?
完整性框架的核心结论是:数据“不被改动”只是第一步,还要保证修改者有权、消息没有重放、状态转换合法、并发不会覆盖、配置和日志可追溯,最终能够通过对账、审计和恢复证明系统仍然可信。