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-01

加密与隐私白皮书

UniClipboard 如何让剪贴板始终是你的:加密、传输、以及设计能守住和守不住的边界。

1. 为什么剪贴板数据必须加密

剪贴板内容的敏感程度被严重低估。在一个普通的工作日里,它会承载:

  • 密码、一次性验证码、API token、助记词
  • 私钥、签名材料、配置片段
  • 内部文档、未发布稿件、私下沟通的草稿
  • 跨设备复制的文件

大多数剪贴板工具把这些数据当作"短暂的、无关紧要的"。但事实上,剪贴板是任何设备上风险最高的数据面之一——存在时间短、频繁通过网络传输、几乎不被审计。

UniClipboard 围绕一个原则构建:

便利不应当以放弃数据的控制权为代价。

本白皮书描述的所有设计,都直接来自这一条原则。


2. 核心安全原则

UniClipboard 的加密体系建立在四条不可妥协的原则之上:

  1. 由用户掌控 加密由用户发起、由用户拥有。密钥从用户口令派生,永远不会由服务端代为生成或托管。

  2. 端到端加密 数据在离开设备前完成加密,只在持有匹配密钥的设备上解密。传输层被视为不可信。

  3. 架构层面的零知识 UniClipboard 的服务端无法读取你的剪贴板内容——这是架构上的事实,不是隐私策略上的承诺。

  4. 最小暴露面 明文只在严格必要的位置出现,停留时间尽可能短,并在内存释放时清零。


3. 总体架构

UniClipboard 围绕**空间(space)**这个概念展开:一组互相信任、共享一段加密剪贴板历史的设备。每个空间拥有独立的主密钥;新设备通过短期有效的邀请码 + 空间口令加入。

空间建立后,数据流如下:

剪贴板内容
   → 本地加密(源设备)
   → P2P 直连通道  ──或──  加密中继回退
   → 本地解密(目标设备)

由此带来的几个直接结论:

  • 优先使用 P2P 直连,跨家庭/办公室网络也通过 NAT 打洞实现
  • 中继节点和任何中间设施只看得到经过认证的密文
  • 网络传输路径不会改变密码学保证——载荷加密与传输独立
  • 信任边界完全位于用户的设备上

4. 密码学原语

UniClipboard 刻意只采用一组小而成熟的现代原语。

用途 原语
认证加密(AEAD) XChaCha20-Poly1305
从口令派生密钥 Argon2id(memory-hard,抗 GPU/ASIC)
AAD 指纹 / 域分离 BLAKE3
本地加密搜索索引 基于 MasterKey 派生的搜索密钥上的 HMAC
随机数 操作系统级 CSPRNG(OsRng)

AEAD 参数

  • 算法:XChaCha20-Poly1305
  • 密钥长度:32 字节(256 位)
  • nonce 长度:24 字节,每条记录由 OS CSPRNG 重新生成。192 位的 nonce 空间使得碰撞在工程意义上完全不必担心。
  • 认证标签:16 字节(Poly1305)
  • AAD:与数据的逻辑身份绑定(见 §5.2)

Argon2id 参数

  • 内存成本:128 MB
  • 迭代次数:3
  • 并行度:4 线程
  • 输出长度:32 字节

这组参数在普通用户设备上仍能维持流畅体验,同时让大规模离线爆破在经济上变得不划算。


5. 密钥管理模型

5.1 分层密钥结构

UniClipboard 通过把"用户秘密"和"加密数据用的秘密"分离开,避免单点泄露。

用户口令(Passphrase)
        │  Argon2id(每空间独立 salt,128 MB · 3 iter · 4 threads)
        ▼
密钥加密密钥(KEK,32 字节)
        │  XChaCha20-Poly1305(KeySlot 包装)
        ▼
主密钥(MasterKey,32 字节,随机生成)
        │  XChaCha20-Poly1305(每条记录绑定 AAD)
        ▼
剪贴板内容 / Blob 存储

各层的职责:

  • 用户口令 —— 永不离开设备,也永不直接用于加密数据。
  • KEK —— 由口令通过 Argon2id 派生,仅用于解包 MasterKey。存放在系统 keyring 中。
  • MasterKey —— 本地随机生成的 32 字节密钥,用于加密该空间内所有的剪贴板条目和 blob。磁盘上只以已包装的形式(KeySlot 文件)存在。
  • 每空间隔离 —— 每个空间持有独立的 MasterKey;切换到另一个空间时,本地历史会在新 MasterKey 下重新加密。

5.2 每条记录的域分离(AAD)

每条加密记录都通过 Additional Authenticated Data(AAD)绑定到自己的身份。AAD 格式带有命名空间和版本号:

uc:inline:v1|<event_id>|<representation_id>      // 内联剪贴板数据
uc:blob:v1|<blob_id>                              // blob 存储

这意味着一段密文要么在原本属于它的位置上解密成功,要么完全不能解密。攻击者无法:

  • 把旧记录重放到另一个槽位
  • 把一段 blob 密文挪到另一个 blob id 下
  • 在事件之间拼接记录

存储侧还会保留一段 16 字节的 BLAKE3 AAD 指纹,用于尽早发现身份不匹配的错误。

5.3 安全本地存储

被包装后的密钥材料分两处存放:

  • 系统 keyring 保存 KEK,使用平台原生的安全存储:
    • macOS —— Keychain
    • Windows —— Credential Manager
    • Linux —— Secret Service(兼容 libsecret)
  • KeySlot 文件 在磁盘上保存被 KEK 包装后的 MasterKey。仅有磁盘访问权限不足以恢复任何明文。

进程内的敏感值(口令、主密钥、明文缓冲区)都装在专用的"秘密容器"类型里:

  • 不能被 clone、序列化、打印或写入日志
  • Debug 与 Display 输出固定为 [REDACTED]
  • drop 时自动将内存清零

6. 剪贴板数据加密策略

6.1 哪些会被加密、哪些不会

UniClipboard 把加密区分成三个相互独立的层次:

  • 应用层(基于 MasterKey) —— 在空间 MasterKey 之下的 XChaCha20-Poly1305。防的是"任何能从磁盘读到原始字节、或经手数据但又不持有 MasterKey 的角色"。
  • 传输层(QUIC) —— 由 iroh 的 QUIC 栈提供,TLS 1.3 风格的 AEAD,由两端各自的长期 Ed25519 设备身份认证。无论里面装什么,线路上的字节都受这层保护。中继也包含在内。
  • 静态存储 —— 落到磁盘的那一份是不是密文。
内容 应用层(MasterKey) 传输层(iroh QUIC) 落盘形式
文本(inline) 加密 加密 密文(每条 AEAD)
图片(blob) 加密 加密 密文(UCBL:zstd + AEAD)
文件载荷字节 不加密(策略性决定) 加密 明文(按 BLAKE3 寻址)
文件元数据 加密 加密 密文(与剪贴板事件一同加密)
搜索索引 加密(HMAC 标签) 不适用 无明文 token(详见 §8)
密钥材料 不适用 不适用 KEK 在系统 keyring;MasterKey 在 KeySlot 文件中以包装态保存

为什么文件载荷不在应用层加密。 这是一项有意为之的范围决定,不是疏忽:

  1. 来源——文件载荷是用户主动复制的内容,其机密性由用户在复制时的意图决定。
  2. 真正会泄露身份的是元数据。 最可能暴露"这是什么文件"的字段——文件名、所在目录、MIME 类型、预览缩略图——并不在文件本体里,而是剪贴板事件本身的一部分;它们和文本一样、在同一空间 MasterKey 之下被加密。
  3. 性能。 把文件视为原始的、内容寻址的字节,可以让大文件传输走 BLAKE3 outboard、APFS / Btrfs / XFS 上的 reflink、Windows 上的外部句柄导入、以及 iroh-blobs 的流式下载路径。再套一层 AEAD 会把这些收益抹平,而对机密性几乎没有额外提升(传输层本身已经有保护)。

实际含义。

  • 在线路上——即便是文件——任何时候都不会暴露原始明文。QUIC 层会对每个 packet 在两端之间做端到端的认证与加密。Wi-Fi 嗅探者、ISP、iroh 中继看到的都只是 QUIC 密文;中继既不持有 QUIC 会话密钥,也不持有任何空间 MasterKey,无法解开 BlobTicket 所指向的内容。
  • 在磁盘上——只有用户自己已配对的设备上——文件载荷会以明文落到内容寻址的本地缓存中。任何能读到该目录的人,或者能进入已登录、已解锁桌面会话的人,都可以恢复出文件字节,本质上跟把文件复制到文件系统是一样的。
  • 引用这些文件的剪贴板事件(文件名、路径、MIME、缩略图等)仍然以加密形式落盘,不解锁空间就读不出来。
  • 对文本和图片来说,字节本身在空间 MasterKey 之下加密落盘,且在线路上叠加 QUIC 传输层加密。

6.2 静态存储布局

  • 剪贴板事件数据库 —— 加密 SQLite 存储;内联文本与结构化 representation 数据按记录加密。
  • 加密 blob 存储(UCBL 格式) —— 用于图片载荷及其它应用层管理的 blob。每个 blob 先经 zstd 压缩,再用 XChaCha20-Poly1305 在 per-blob AAD 下加密;文件头为 [UCBL magic | version | nonce]。
  • 内容寻址的文件缓存 —— 由 iroh-blobs 提供。文件载荷以原始字节存放,按 plaintext 的 BLAKE3 哈希寻址。该缓存不在应用层加密(见 §6.1)。
  • 搜索索引 —— 以 HMAC term 标签为键的倒排索引(见 §8),不含明文 token。
  • 密钥材料 —— KEK 存于系统 keyring;包装后的 MasterKey 写入磁盘上的 KeySlot 文件。

7. 同步安全模型

UniClipboard 的传输基于 QUIC P2P 网络(iroh)。在它之上叠加了两层互相独立的加密:

  • iroh QUIC(传输层) —— 所有连接(剪贴板事件、blob 拉取、在线状态、配对)都跑在 QUIC 之上,使用 TLS 1.3 风格的 AEAD,由两端各自的长期 Ed25519 身份认证。无论里面装什么,线路上的所有字节都受这层保护。中继只转发已经加密的 QUIC 数据报,不持有任何能解密的密钥材料。
  • MasterKey(应用层) —— 在 QUIC 之上,剪贴板事件与图片 blob 还会额外用 XChaCha20-Poly1305 在空间 MasterKey 下再加密一遍,这样即便一台已经接入 iroh 网络但不持有 MasterKey 的端点,也读不出内容。如 §6.1 所述,文件载荷不享有这第二层保护——在传输中只依赖 QUIC 端到端加密。

7.1 配对与设备身份

  • 每台设备首次启动时在本地生成长期的密钥对。
  • 加入空间需要邀请码(短期有效,几分钟内过期)+ 空间口令。没有邮箱、没有账号、没有云端注册。
  • 配对信息保存在本地;从任意一台已配对设备上撤销某台设备后,下次同步立刻不再包含它。

7.2 局域网同步

  • 同一 Wi-Fi 下的设备直接互联,不经过任何外部基础设施。
  • 载荷在到达网线之前就已用空间 MasterKey 加密。
  • 抓包只能拿到密文。

7.3 跨网络同步

当两台设备无法直连时,UniClipboard 通过 NAT 打洞建立 P2P 连接。如果打洞失败:

  • iroh 中继在双方之间转发 QUIC 数据报。
  • 中继只看得到 QUIC 密文以及连接元数据(peer ID、时间戳)。它既不持有 QUIC 会话密钥,也无从持有空间 MasterKey。
  • 中继无法派生密钥、无法解密、也无法在不被发现的情况下篡改内容——QUIC 层(始终)和 MasterKey 层(文本与图片)的 AEAD 认证标签都会捕获篡改。
  • 中继是可自建的:你可以让 UniClipboard 指向自己的中继节点,并用内置的连通性测试确认配置可用——跨网络同步因此无需经过任何你不掌控的基础设施。
  • 仅局域网(LAN-only)模式会彻底关闭中继和所有公网路径——已配对设备此时只走局域网发现与直连,任何数据都不会离开你的局域网。

7.4 剪贴板事件的 wire format

剪贴板事件使用分块的应用层 wire format:

  • 把载荷切分为有界的 chunk(大事件不必整个装入内存)
  • 每个 chunk 在加密前用 zstd 压缩
  • 每个 chunk 在 (transfer_id ‖ chunk_index) 的 AAD 下被认证,因此 chunk 不能被乱序、丢弃或重放
  • 头部带有版本号(UC3\0),以便未来格式升级可以平滑过渡

大型文件载荷走的是另一条传输层原生路径:发送端把文件加入自己的 iroh-blobs 存储并签发一张 BlobTicket;ticket 通过加密的剪贴板事件发给接收端;接收端在带 BLOBS_ALPN 协议标识的 QUIC 流上拉取 blob。该 QUIC 流本身被加密(见 §7.3),但流内的 blob 字节不会再被 MasterKey 二次加密(见 §6.1)。

7.5 韧性

切换 Wi-Fi、休眠唤醒、短暂断网后,连接会自动恢复,无需重新配对。


8. 本地加密搜索

UniClipboard 在历史规模达到数万条时仍能在毫秒级完成全文搜索,并保持索引在磁盘上加密。

  • 搜索密钥派生 —— 解锁后,从 MasterKey 派生出专用的搜索密钥,与内容加密用的密钥分离。
  • Term 标签 —— 每个 token 在写入倒排索引前会被替换为 HMAC(search_key, normalized_token)。磁盘上不会出现明文搜索词。
  • 会话锁感知 —— daemon 在锁定状态下不会捕获或索引新的剪贴板内容;解锁之前搜索功能不可用。索引重建只发生在解锁状态下。
  • 规范化 —— 稳定且带版本的规则(Unicode NFKC、转小写、合并空白、剥离 HTML 标签、URL 与路径切分)。索引中保存 index_version,以便未来规则变化能触发安全的重建。
  • 分词 —— 混合策略:拉丁文字、数字、路径段、URL 片段、文件名采用词级切分;中文使用 bigram。这与剪贴板内容常见的混合形态(自然语言、shell 命令、代码、URL、文件路径、中英混排)相匹配。

搜索子系统只做必要的取舍:它不试图隐藏本地访问模式或本地查询频率——这些信息对已经能访问到解锁机器的人来说本就是可观察的。


9. 本地 Daemon API

桌面 GUI 和 uniclip 命令行都通过 HTTP + WebSocket 与本地后台 daemon 通信。daemon 经过专门加固以抵御本地误用:

  • 仅 loopback —— daemon 仅监听 127.0.0.1,流量永远不离开本机。
  • Bearer → Session 交换 —— 一个保存在 chmod 600 文件中的 bearer token 用于换取短期会话 JWT(5 分钟有效,HS256 签名,密钥 32 字节)。
  • PID 白名单 —— 每个会话与调用方进程的 PID 绑定;PID 不匹配会被拒绝。
  • 限流 —— 每客户端每分钟 100 次,滑动窗口。
  • 不在客户端持久化 —— 会话 token 仅存在于内存中;不会写入 localStorage、sessionStorage 或 cookie。
  • 纵深防御 —— 鉴权先于限流执行;危险端点(如清空缓存)必须显式带上 confirmed: true。

以上属性已在内部 phase 级别的安全审计中得到验证。


10. 威胁模型

10.1 UniClipboard 抵御的威胁

威胁 是否抵御
局域网的 Wi-Fi 嗅探 是
中继链路上的窃听 是
服务端 / 中继节点被攻陷 是
云端或第三方存储被攻陷 是
中继上的主动 MITM 是
失窃设备的磁盘被读取(非活跃状态) 是
在不同槽位之间重放或拼接记录 是
本地非特权进程访问 daemon 是

10.2 明确的非目标

UniClipboard 不声称能够抵御以下场景:

  • 设备已被完全攻陷(root 级恶意软件、键盘记录、有恶意权限的管理员)
  • 用户主动泄露口令
  • 在用户已登录、设备已解锁的情况下被取证
  • 拥有完整本地权限的人能观察到的旁路(例如原始访问模式)
  • 直接读取本地文件缓存中的文件原始字节。 见 §6.1:文件载荷以内容寻址的原始字节形式落盘,不在应用层加密;与之相关的元数据(文件名、路径、MIME、缩略图)仍作为剪贴板事件的一部分被加密。

只有把威胁边界讲清楚,安全声明才有意义。我们把非目标也列出来,是为了让用户能够做出明智的判断。


11. 用户控制与可验证性

用户可以:

  • 在首次启动时启用或不启用加密初始化,并在之后轮换
  • 切换到另一个空间;本地历史会在新空间的 MasterKey 下重新加密
  • 立即暂停同步
  • 在任意一台已配对设备上撤销丢失或被盗的设备——下次同步起空间不再包含它
  • 随时关闭匿名遥测。遥测从不携带剪贴板内容或个人数据。

完整源代码——包括本文描述的每一项密码学操作——已在 GitHub 以 AGPL-3.0 协议开源。请相信代码本身,而不是市场宣传。


12. 结语

UniClipboard 中的加密不是一个可选功能、不是一项市场宣传项、也不是收费版的卖点。

它是产品的地基。

我们的信念是:

  • 你的数据属于你
  • 同步不等于托管
  • 隐私不应当用便利来交换

本文中的每一项架构决策,都直接来自这三句话。

本页目录

  1. 1. 为什么剪贴板数据必须加密
  2. 2. 核心安全原则
  3. 3. 总体架构
  4. 4. 密码学原语
  5. 5. 密钥管理模型
  6. 6. 剪贴板数据加密策略
  7. 7. 同步安全模型
  8. 8. 本地加密搜索
  9. 9. 本地 Daemon API
  10. 10. 威胁模型
  11. 11. 用户控制与可验证性
  12. 12. 结语
UniClipboard

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

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