文字先加密,再出发。
Input Relay 的输入内容采用端到端加密。文字在发送设备上加密,由目标 Mac 解密后提交给当前应用。应用优先尝试局域网直连,其次尝试 WebRTC P2P;无法直连时,中继服务负责转发加密消息,不持有用于解密输入内容的密钥。
具体实现使用 AES-256-GCM:既加密内容,也验证消息是否被篡改。每条消息使用随机的 12 字节 nonce;收发设备身份同时参与认证,不能只改一个目标设备编号就让另一台电脑接受消息。
设备在本地生成并保管共享秘密,通过 HKDF-SHA256 为每一对设备、每个传输方向派生密钥。Mac 使用系统 CryptoKit,Android 使用系统密码库。局域网直连、P2P 和中继都保留这层内容加密。中继连接另有 HTTPS / WSS 保护,WebRTC 使用 DTLS;局域网 TCP 也必须通过已有配对密钥的双向验证,发现设备不等于信任设备。
六位数字很短,信任不能省略。
输入的六位配对码用于找到一次邀请,它不是加密密钥。通过数字码添加设备时,两端使用临时的 P-256 密钥进行 ECDH 密钥交换,并显示用于核对的确认码。请核对两端显示的数字,再按应用提示确认。
输入六位配对码
比对两端确认码
加密传递配对信息
双方先提交公钥与随机数的摘要,再公开对应数据并验证,避免一方看到对方的数据后再随意修改自己的交换内容。经确认后,配对信息通过 AES-GCM 加密传递,服务器不接收明文加密密钥。
二维码是另一种邀请入口,包含配对所需的信息,并不只是六位数字,因此也不应公开分享。邀请只可使用一次;配对完成会消耗邀请,关闭展示页面会请求撤销。遇到断网等无法及时撤销的情况,服务器仍保留最长五分钟的超时兜底。
服务器知道连接,不知道正文。
为了找到设备并转发消息,服务仍需要处理一些连接信息。端到端加密保护输入内容,不意味着使用过程完全匿名。
服务器可以处理
- 设备名称、类型与关联关系
- 设备在线状态、收发设备标识
- 经中继传输的消息时间与密文大小
- 连接链路上的网络信息,例如 IP 地址
中继不接收明文
- 你发送的文字与按键指令
- Mac 返回的目标应用状态
- 用于解密内容的设备共享秘密
直连成功后,输入内容不经过中继。服务器仍参与设备在线状态、撤销授权与加密连接协商;STUN 帮助寻找可直连的地址,不承载输入文字。目前仍需要服务器协调,不支持服务器离线模式。
中继保存设备与鉴权所需的数据,例如令牌和邀请的哈希;输入内容不写入服务端历史,也没有离线消息队列。目标电脑离线时,不会在它上线后自动补发积压文字。
历史留在本机,由你管理。
发送端和接收端分别保存自己的历史,包含文字、对端设备和目标应用等信息,不上传为云端历史。默认保留数量为无限,你可以设置上限、删除单条或清空全部。删除一端的历史,不会同步删除另一端的记录,也不会删除已经写入目标应用的内容。
历史数据库目前没有额外的应用层加密。它保存在各自设备的应用数据目录,依靠操作系统的访问控制与设备自身的存储保护。能访问该目录的人或程序,可能读到记录。
配对信息与历史分开保存:Android 的配对配置使用 Android Keystore 管理的密钥加密;Mac 使用仅当前用户可访问的本地文件,不使用钥匙串存储配对信息。Mac 的这份文件没有额外加密,因此设备账户本身也需要受到保护。
明确边界,才有可靠的信任。
你的已连接设备处于同一个信任范围,共享用于派生密钥的根秘密。不同方向的密钥可以区分消息用途,但不能把已经可信的设备彼此隔离。当前版本不提供前向保密:如果根秘密泄露,攻击者可能解密此前保存的相关密文。
移除设备会撤销它的服务端访问权限,但不会让它遗忘已经持有的秘密,也不会自动轮换其他设备的根秘密。这不是对旧数据的密码学撤销。
Mac 会检查输入授权、锁屏与安全输入状态,并用会话标识、短时有效凭据和递增序号拒绝过期或重复的输入。它仍无法保护已经被恶意软件控制的设备,也无法替代你所用输入法、语音服务或目标应用自身的隐私保护。
这篇文章描述的是当前实现,不是独立安全审计报告。加密算法的选择只是其中一部分;正确核对配对信息、保护已连接设备,同样重要。