敏感数据方案设计 V1
mingzaily / 2023-08-31
一、方案定位与核心目标
1. 定位
针对中小型项目或轻量业务场景(如用户中心、会员系统),通过 “独立加密服务 + 业务服务协作” 的模式,结合 “字段拆分” 设计,实现身份证号、手机号等敏感信息的安全存储与查询。无需部署重量级中间件,兼顾成本控制与基础安全合规要求,适配现有微服务架构。
2. 核心目标
- 敏感信息不明文落地:数据库仅存储加密后的数据与非敏感特征,从源头杜绝明文泄露风险;
- 服务解耦协作:加密逻辑封装为独立服务,与业务服务通过标准化 API 交互,避免代码耦合与安全逻辑分散;
- 查询能力适配:支撑精准查询与固定模糊查询,满足用户登录、归属地筛选等常见业务需求;
- 低门槛落地:基于现有技术栈扩展,开发运维成本可控,无需团队掌握复杂中间件技能。
二、方案架构设计(独立服务协作模式)
1. 整体架构
核心为 “业务服务 + 独立加密服务 + 存储层” 的协作架构,服务间通过 API 契约交互,各组件职责明确,可独立部署与扩展:
2. 核心组件说明
| 组件 | 核心职责 | 关键交互逻辑 |
|---|---|---|
| 业务服务集群 | 1. 接收用户 / 运营端请求;2. 调用加密服务处理敏感信息;3. 读写业务数据库;4. 返回业务结果并记录日志 | 1. 通过 HTTP/GRPC 调用加密服务 API;2. 执行 SQL 操作业务数据库 |
| 加密服务集群 | 1. 提供加密、解密、哈希验证 API;2. 内置密钥管理(存储于 KMS 或本地安全文件);3. 记录操作审计日志;4. 实现防重放、限流等安全防护 | 1. 响应业务服务的 API 请求;2. 内部读写密钥与审计日志 |
| 业务数据库 | 1. 存储 “加密字段 + 哈希字段 + 预留特征字段”;2. 无任何完整明文敏感信息 | 仅接收业务服务的 SQL 操作,拒绝其他直接访问 |
| 业务日志存储 | 记录业务服务的操作日志(如用户上传敏感信息、运营查询用户列表),支撑业务问题排查 | 仅接收业务服务的日志写入请求 |
三、核心设计细节
1. 数据库字段拆分规则(核心安全设计)
针对不同敏感信息,采用 “三段式字段拆分”,确保单字段泄露无风险,同时适配查询需求:
(1)身份证号字段设计(用户表)
| 字段名 | 类型 | 长度 | 用途说明 | 安全属性 |
| id_card_enc | VARCHAR | 255 | 存储加密服务返回的身份证号密文;仅用于 “存储”,不参与查询 | 敏感(需密钥解密) |
| id_card_hash | VARCHAR | 64 | 存储加密服务生成的 SHA-256 哈希值(带随机盐);用于 “精准查询”(如验证身份证号唯一性) | 非敏感(不可反推明文) |
| id_card_reserve | VARCHAR | 20 | 存储身份证号前 6 位(行政区划码)+ 后 4 位;用于 “固定模糊查询”(如筛选某地区用户) | 非敏感(公开信息) |
(2)手机号字段设计(用户表)
| 字段名 | 类型 | 长度 | 用途说明 | 安全属性 |
| phone_enc | VARCHAR | 255 | 存储加密服务返回的手机号密文;仅用于 “存储”,不参与查询 | 敏感(需密钥解密) |
| phone_hash | VARCHAR | 64 | 存储加密服务生成的 SHA-256 哈希值(带随机盐);用于 “精准查询”(如手机号登录验证) | 非敏感(不可反推明文) |
| phone_reserve | VARCHAR | 20 | 存储手机号前 7 位(归属地编码);用于 “固定模糊查询”(如筛选某运营商 / 地区用户) | 非敏感(公开信息) |
设计原则:
-
加密字段(enc):仅由加密服务生成,业务服务 “只存不解”(需解密时必须调用加密服务);
-
哈希字段(hash):避免业务服务传输明文进行匹配,降低传输过程中的泄露风险;
-
预留字段(reserve):仅存非敏感特征,无需调用加密服务即可完成模糊查询,减少服务交互成本。
备注:加密字段仅用于数据存储,禁止作为查询条件;哈希字段必须带随机盐值,避免彩虹表反推风险;预留字段需根据业务查询需求提前定义,仅保留非敏感特征。
2. 加密服务核心能力(安全边界封装)
加密服务是方案的安全核心,所有敏感操作均在内部封装,对外仅暴露标准化 API:
(1)核心 API 设计(GRPC/HTTP 双支持)
| API 名称 | 请求参数 | 返回结果 | 用途说明 | 安全控制 |
| EncryptData | data(明文)、type(idcard/phone) | encrypted_data(密文)、hash(哈希值)、request_id | 加密敏感信息,同步返回密文与哈希值 | 1. 需 appId+appSecret 认证;2. 请求需携带时间戳 + 签名(防篡改) |
| DecryptData | encrypted_data(密文)、type(idcard/phone) | data(明文)、request_id | 解密敏感信息,返回明文 | 1. 需 appId+appSecret 认证;2. 单 IP 限流(默认 100 QPS) |
| VerifyHash | data(明文)、hash(存储的哈希值)、type | is_match(布尔值)、request_id | 验证明文与存储的哈希值是否匹配 | 需 appId+appSecret 认证 |
(2)内置安全能力(无需业务服务关注)
- 密钥管理:采用 “一类型一密钥”(身份证号与手机号使用不同密钥),密钥优先存储于轻量 KMS(如阿里云 KMS 入门版);无 KMS 时存储于本地安全文件(权限 600,仅加密服务进程可读写);
- 操作审计:每一次 API 调用生成唯一 request_id,记录 “调用方 appId、请求时间、操作类型、数据类型”,日志留存 6 个月,支持安全审计与问题追溯;
- 防攻击防护:API 请求需携带 “5 分钟内有效时间戳 + SHA256 签名”(签名规则:sign = SHA256(appSecret + timestamp + request_body)),避免重放攻击;
- 服务高可用:内置健康检查接口(/health),支持服务注册与负载均衡,节点故障时自动剔除。
备注:加密服务需独立部署,禁止与业务服务混部;API 签名密钥需定期更换(建议每 3 个月),更换时需提前同步给业务服务,避免接口调用失败;审计日志需包含完整操作上下文,便于泄露事件追溯。
四、安全与运维设计
1. 权限管控(边界隔离)
- 服务间权限:业务服务调用加密服务需通过 “appId+appSecret” 认证(运维人员在加密服务控制台配置),不同业务服务分配独立 appId,禁用后立即失效;
- 数据库权限:仅开放业务服务的 “应用账号” 访问用户表,运维 / 开发人员需通过 “审批流程” 获取临时查询权限,且查询结果中 “enc 字段” 自动脱敏(显示为 ***);
- 密钥访问权限:仅加密服务的 “服务账号” 可访问密钥存储(KMS / 安全文件),禁止任何其他服务或人员直接接触密钥。
备注:权限审批需留痕,临时权限有效期不得超过 24 小时;数据库访问需开启 SQL 审计,记录所有查询操作,重点监控敏感字段的访问行为。
2. 高可用保障
- 加密服务:部署 2 + 节点,通过服务注册中心(如 Nacos/Eureka)实现负载均衡,单节点故障不影响整体服务;
- 业务服务:按业务模块独立扩容,与加密服务扩容逻辑解耦;
- 业务数据库:采用主从架构,主库负责写入,从库负责查询,避免单点故障;敏感字段所在表开启行级锁,减少并发查询冲突。
备注:加密服务需配置熔断机制,当调用失败率超过 5% 时自动触发降级,避免级联故障;数据库主从同步延迟需控制在 1 秒内,确保查询结果一致性。
3. 合规性落地(基础等保要求)
- 数据脱敏:所有前端展示、日志打印、接口返回中,敏感信息强制脱敏(手机号:1380001,身份证号:11020000101****);
- 数据备份:业务数据库每日全量备份,备份文件用独立密钥加密存储,保留 30 天,支持按时间点恢复;
- 应急响应:加密服务故障时,业务服务自动降级(暂停敏感信息上传,提示 “系统维护中”);数据库泄露时,因仅存加密字段,需优先排查加密密钥安全性(密钥未泄露则数据无风险)。
备注:脱敏规则需统一(如手机号中间 4 位脱敏、身份证号中间 8 位脱敏),禁止部分场景脱敏、部分场景明文;备份文件需定期(每月 1 次)验证恢复有效性,避免备份失效;应急响应预案需每季度演练 1 次,确保故障发生时可快速处理。
五、常用问题解答(FAQ)
1. 业务服务与加密服务通信延迟高怎么办?
- 优先采用 GRPC 协议(比 HTTP 传输效率高 30%+);
- 加密服务与业务服务部署在同一机房 / 可用区,减少网络延迟;
- 非必要不调用解密接口(如仅需验证身份证号唯一性,仅调用 EncryptData 获取哈希值即可)。
备注:可在业务服务端对高频查询的哈希值做本地缓存(如 Redis 缓存,有效期 5 分钟),减少加密服务调用次数,但需注意缓存失效时的一致性问题。
2. 为什么要单独做加密服务,不直接在业务服务中实现加密逻辑?
- 解耦安全逻辑:加密算法升级或安全规则调整时,仅需修改加密服务,无需所有业务服务迭代;
- 统一安全边界:所有敏感操作集中在加密服务,便于审计与安全管控,避免业务服务 “各自实现加密” 导致的漏洞;
- 权限隔离:业务开发人员无需接触加密密钥,降低密钥泄露风险。
备注:若业务服务直接实现加密逻辑,需在每个服务中维护密钥,易导致密钥泄露;且不同业务服务可能采用不同加密算法,增加安全管控复杂度,不符合 “安全逻辑集中化” 原则。
3. 预留字段能支持多维度模糊查询吗(如手机号前 3 位 + 后 4 位)?
- 支持,但需提前设计预留字段格式。例如将 phonereserve 设计为 “前 3 位后 4 位”(如 1380001),查询时执行 WHERE phone_reserve LIKE ‘138%0001’即可;需注意:预留字段格式需在业务初期确定,避免后期修改导致历史数据不兼容。
备注:预留字段的设计需结合实际业务查询需求,避免过度冗余;若需支持多维度查询,可将预留字段拆分为多个子字段(如 phone_prefix3、phone_suffix4),便于精准匹配,提升查询性能。
六、方案优势与适用场景
1. 核心优势
- 低成本落地:无需部署 Vault、K8s 等重量级组件,基于现有微服务架构扩展,开发运维成本可控;
- 安全合规:满足 “敏感信息不明文存储、操作可审计、权限隔离” 的基础等保要求;
- 查询高效:精准查询依赖哈希索引,模糊查询依赖预留字段,无频繁跨服务调用;
- 易扩展:加密服务与业务服务解耦,可独立升级或替换(如后续迁移到 Vault 时,仅需修改加密服务内部逻辑,不影响业务服务)。
2. 适用场景
- 中小型项目或创业公司,预算有限,无复杂中间件运维能力;
- 敏感信息查询场景简单(以精准查询、固定模糊查询为主),无动态模糊需求;
- 团队已采微服务架构,希望安全逻辑与业务逻辑解耦;
- 合规要求为基础等保(如等保 1.0),无需金融级高安全标准。