UniClipboard
在线试用博客对比使用场景文档更新日志赞助
下载
UniClipboard

在你自己的设备之间同步剪贴板,开源开发。

链接
仓库IssuesReleases文档赞助支持
技术栈
RustTauriirohshadcn/ui
联系
X · @uniclipboardX · @mkdir700B站 · @mkdir700[email protected]
© 2026 mkdir700made with Rust 🦀 · AGPL-3.0
UniClipboard
在线试用博客对比使用场景文档更新日志赞助
下载
UniClipboard

在你自己的设备之间同步剪贴板,开源开发。

链接
仓库IssuesReleases文档赞助支持
技术栈
RustTauriirohshadcn/ui
联系
X · @uniclipboardX · @mkdir700B站 · @mkdir700[email protected]
© 2026 mkdir700made with Rust 🦀 · AGPL-3.0
UniClipboard
在线试用博客对比使用场景文档更新日志赞助
下载
首页博客加密搜索原理

最后更新·2026-05-09

加密搜索原理

索引在磁盘上加密,搜索靠 HMAC term tag 命中,而不是明文词。

UniClipboard 的隐私前提是:所有剪贴板记录加密存储,搜索索引也加密。

磁盘上没有任何一处保存明文剪贴内容。索引的加密细节见「同步内容 — 本地存储」。

现在的问题就是:内容都加密了,搜索框该怎么命中里面的字?

怎么建索引

UniClipboard 走的是「分词 → HMAC token 化 → 倒排索引」这条路:

  1. 内容先做 NFKC 归一化 + 小写,再按 Unicode 词边界分词
  2. 每个 token 经过一次 HMAC-SHA256(SearchKey, token),产出一个 32 字节的 term tag
  3. 倒排索引里存的就是 term tag,不存原文

SearchKey 由空间 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 切

中文走“重叠两字”切分。你好世界 在索引里是 你好 / 好世 / 世界 三个 bigram,每个都建 term tag。

所以搜 好世 能命中 你好世界,搜 你好 也行。多字中文片段里的单字搜索不行 —— 索引里没有单字这一层。

这对日常使用意味着什么

想找 推荐搜
一段含 prod 的命令 直接搜 prod,别搜 pro
文件名带 report 搜 report,或者它的前缀 rep、repo 也行
中文短语 用至少两个字的连续片段(比如 合同,而不是 合)
拼不准的英文词 换更短但完整的 token,再用类型 / 时间过滤缩范围

更多查询语法见「全文搜索 — 查询语法」。

本页目录

  1. 怎么建索引
  2. 怎么命中
  3. 边界:正文里子串搜不到
  4. 这对日常使用意味着什么
UniClipboard

在你自己的设备之间同步剪贴板,开源开发。

链接
仓库IssuesReleases文档赞助支持
技术栈
RustTauriirohshadcn/ui
联系
X · @uniclipboardX · @mkdir700B站 · @mkdir700[email protected]
© 2026 mkdir700made with Rust 🦀 · AGPL-3.0