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

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 条回复
xmsl
8 月 4 日
受教了!很好的教程
opengps
8 月 4 日
如果允许弱一点,其实可用解绑的方案来模糊查询,就是所有手机号明文,但是个独立的单列表(手机号没直接绑定到用户 id 上),模糊查询之后,密文跨表关联
itechnology
8 月 4 日
@opengps 你这个方案不咋行吧?一般场景都是看你数据库有没有明文保存手机号,并不是说你没有关联用户 id 就没关系了。
opengps
8 月 4 日
@itechnology #3 所以说也是个弱方案,至少做到解绑了直接关系,数据库被脱裤也只是知道有这个手机号,但不一定知道这个号是哪个 id 的
shintendo
8 月 4 日
手机号模糊搜索这需求感觉好奇怪
itechnology
8 月 4 日
@shintendo 不奇怪啊,这种需求很常见。
WaldenHorizon
8 月 4 日
如果是为了过等保,防止别人拿走物理文件,在存储层开启加密就行了,不影响应用层任何功能
我之前不了解这个东西做等保的时候,产品要求手机号精确搜索,是在代码层用相同的加密方式和密钥处理搜索字符串,然后精确搜索密文
AutumnVerse
8 月 4 日
ngram 分词后,拿到你 ngram 数组的结果,不就能反推出手机号了吗?最后还是相当于明文存储
ajaxfunction
8 月 4 日
糟糕,我完全是明文,只是前端显示的时候是 脱敏的
AutumnVerse
8 月 4 日
我的方案,es 里面存两份数据
第一份跟你的 hash 一致,用于精确搜索
第二份是 138901***42 这种部分打码的数据,这样能用前缀搜索,也能用尾缀做区分
shintendo
8 月 4 日
@itechnology 一般精确搜索或者尾号 4 位搜索就可以了吧,这个任意位置搜索岂不是可以反推明文
wu00
8 月 4 日
搜索 8562 ,出结果 186****8866 ?
Dxxxxs
8 月 4 日
@AutumnVerse #8 HMAC 不就是解决这个问题的吗
theliang
8 月 4 日
这用户量大的时候这索引有点恐怖
gouLang
8 月 4 日
也就是说 11 位的手机号从前四位开始不断向右滑, 每次切四位, 生成 phonetokens 吗, 一共切八次?
Tsing2
8 月 4 日
如果这是面试题的话:
1. 不用可逆的加密,用哈希。
2. 存完整手机号的哈希。
3. 存前四位的哈希。
4. 存后四位的哈希。
以上是最基本的思路,根据 PRD 作相应修改
chjqpmain
8 月 4 日
果然我在真实项目的全周期中一堆东西都不知道,感谢分享,要继续了解
visper
8 月 4 日
用假加密,一一对应。
itechnology
8 月 4 日
@gouLang 是的
potatowish
8 月 4 日
是我孤陋寡闻了,对于手机号、身份证号的,我只见过精准匹配查询

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

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

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

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

© 2021 V2EX