最后更新·
索引在磁盘上加密,搜索靠 HMAC term tag 命中,而不是明文词。
UniClipboard 的隐私前提是:所有剪贴板记录加密存储,搜索索引也加密。
磁盘上没有任何一处保存明文剪贴内容。索引的加密细节见「同步内容 — 本地存储」。
现在的问题就是:内容都加密了,搜索框该怎么命中里面的字?
UniClipboard 走的是「分词 → HMAC token 化 → 倒排索引」这条路:
HMAC-SHA256(SearchKey, token),产出一个 32 字节的 term tagSearchKey 由空间 MasterKey 通过 HKDF-SHA256 派生(每个空间一把),MasterKey 存在系统密钥环,离开本机就拿不到。
这意味着即使索引文件被人拿走,看到的也只是一堆 HMAC 输出 —— 不可逆,反推不出原始 token。
查询时走完全相同的一套 token 化 + HMAC,命中“完整 term tag”才算匹配。
拿 hello world 举例:
| 输入 | 命中 hello world |
|---|---|
hello |
✅ |
world |
✅ |
hello world |
✅(两个 term tag 都要命中) |
hel |
❌ |
ello |
❌ |
hel 搜不到 hello,是因为 HMAC 是整体变换 —— 输入差一个字符,输出就完全不同。hel 和 hello 在 term tag 空间里没有任何前缀关系。
所以在正文里,子串搜不到,必须用完整的词。
这是加密搜索的弊端。如果允许任意子串匹配,索引里就得保留能反推明文的“缝隙”(比如把所有 n-gram 都建进索引、或者保留可比较的明文前缀),加密的意义就被削弱了。
UniClipboard 在两个地方做了让步,让搜索体验不至于太难受:
文件名、URL、路径这类标识符类字段在建索引时,会把每个 token 的前缀(长度 ≥ 3)单独算一份 term tag。
所以搜 uniclip 能命中文件名 uniclipboard.dmg,搜 localh 能命中 URL localhost:3000。
这只对标识符字段开启 —— 大段正文不开,否则索引体积会失控。
中文走“重叠两字”切分。你好世界 在索引里是 你好 / 好世 / 世界 三个 bigram,每个都建 term tag。
所以搜 好世 能命中 你好世界,搜 你好 也行。多字中文片段里的单字搜索不行 —— 索引里没有单字这一层。
| 想找 | 推荐搜 |
|---|---|
一段含 prod 的命令 |
直接搜 prod,别搜 pro |
文件名带 report |
搜 report,或者它的前缀 rep、repo 也行 |
| 中文短语 | 用至少两个字的连续片段(比如 合同,而不是 合) |
| 拼不准的英文词 | 换更短但完整的 token,再用类型 / 时间过滤缩范围 |
更多查询语法见「全文搜索 — 查询语法」。