手机号你们通常怎么在加密保存的同时兼具模糊搜索的功能?

8 月 4 日
 itechnology

我目前的方案是这样的:

1 、手机号经过 AES-GCM 对称加密后保存到数据库,每次加密会随机生成向量 IV ,保存到数据库的值是“向量 IV:密文”,秘钥是全局唯一的(保存在 nacos 中)。

2 、为了支持手机号模糊搜索,我利用了项目中现成的 es ,文档的结构如下:

@Data
@Document(indexName = "user_phone_index")
public class UserPhoneDocument {

    @Id
    private String id; // 与 MySQL 的 userId 一致

    @Field(type = FieldType.Keyword)
    private Long userId;

    /**
     * 带位置的 N-Gram HMAC 盲索引数组(对 "位置:四位切片" 哈希),必须为 keyword 类型。
     * 例:0:1381 、1:3812 → 各自 HMAC
     */
    @Field(type = FieldType.Keyword)
    private List<String> phoneTokens;

    // 存储完整手机号的 HMAC (用于精确搜索)
    @Field(type = FieldType.Keyword)
    private String phoneFullHash;

}

phoneTokens 和 phoneFullHash 都会用全局唯一的 hmac key (保存在 nacos )进行哈希。

phoneTokens 是一个滑动切片,固定四位,每次向右滑动一位。

这样设置以后,就可以做到模糊搜索,但要求搜索时至少输入 4 位数以上。

4757 次点击
所在节点    程序员
34 条回复
nullico
8 月 4 日
感觉没必要,现在绝大多数场景要不就是精确搜索,要不就是尾号四位。当然,可能你产品比较特殊,不过我觉得绝大多数场景都没必要这么复杂,很直接全部和尾号这部分 hash 一下都行,然后直接搜这个
itechnology
8 月 4 日
@shintendo 如果项目场景已经确定了只会有精确搜索或者手机 4 位尾号搜索,那就不需要引入 es 了,直接建两个辅助字段,分别保存完整手机号 HMAC 和手机 4 位尾号 HMAC 就可以了,比我这个方案要简单、方便很多。
SoulFlame
8 月 4 日
以前我是自己写了一套映射算法,然后存储映射后字符串,别人乍一看数据库存储的似乎就是加密了。应付下得了
nnnnnnamgn
8 月 4 日
没做过类似的业务,要整个手机号加密存储的场景是什么?
ming2050
8 月 4 日
话说这个安全需求是怎么产生的
xiangbohua
8 月 4 日
@opengps 你的关联表在哪?跨表关联那关联表意思在一个库里面,然后库被脱了,那不还是明文啊
opengps
8 月 4 日
@xiangbohua #26 密文列是用密钥临时算的,算完了才有完整临时表可用来跨表关联
ala2008
8 月 4 日
我们之前做 3 级等保,存储加密,直接干掉搜索功能,不能搜索手机号 这些都有现成方案吧,淘宝、jd 、拼多多开发文档
rammiah
8 月 4 日
@ming2050 #25 手机号等敏感信息有的备案要求加密存储,但是产品里有模糊搜索的需求
xndeye
8 月 4 日
手机号这种固定格式数据通常不会做全文模糊吧?一般也就是 完整匹配、前三位+后四位匹配、后 4 位匹配 三种情况,直接做盲索引就行了
DengDDDD
8 月 4 日
做 单字节 hash+密文串, 模糊查询查前面部分
everfly
8 月 4 日
可以了解下同态加密和 PIR (私有信息检索)/ PSI (私有集合求交),这是苹果联系人搜索用的框架。
Mandelo
8 月 5 日
善用 GPT ,方案几乎和你一样,“PHONE_ENCRYPT:AES 加密后的真实手机号
PHONE_HASH:完整手机号的 HMAC ,用于精确查询
PHONE_MASK:脱敏展示
SYS_USER_PHONE_INDEX:保存手机号片段的 HMAC ,用于模糊搜索

不要直接使用普通 SHA-256 。手机号取值空间很小,攻击者可以枚举手机号反查哈希。应使用带密钥的 HmacSHA256 。”
dingwen07
8 月 5 日
@Tsing2 国内号段就那几个
别说前后 4 位了
完整手机号的哈希撞起来都不要太轻松
加盐哈希就没法搜索了,而且手机号就算加了盐撞起来也很快

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://v2ex.ih06.com/t/1231907

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX