“发送端从nonce分配器取一个未用过的s,调用AEAD得到 $C=\mathrm{Enc} {K d}(N,A,M)$,线上记录为 $(A,C)$。头部受认证但不保密;序号映射对合法64位s…”
形式陈述
AEAD的nonce-respecting游戏把“同一密钥下加密nonce不重复”交给调用方。本页证明的是这项状态不变量,不重证AEAD保密或完整性。固定一个方向密钥
稳定状态 next,end。固定块大小 next=d,end=D';若 next=end 时必须重新预留。重启只读D,置 next=end=D,故以前预留但未使用的号全部跳过。
不变量为:每次实际加密使用的
直觉
先发记录、再保存计数器,会留下断电窗口:记录已经被攻击者看到,计数却没有落盘,重启后又发同一号。预留把顺序倒过来,让系统宁可浪费未使用的号,也不重新使用已经可能出现过的号。
无崩溃且完整用完每块时,每B个号一次稳定写,每次取号只做常数个计数操作,稳定状态和内存状态都为常数空间。频繁崩溃可能每次只用一个号甚至一个也未用,实际稳定写摊销不能无条件仍算1/B。预留块越大,每条记录在顺利运行时分摊的稳定写越少,崩溃时可能跳过的号越多。这是写入成本与号码消耗的权衡,不改变安全不变量。
例子与边界
取 0,1,4,5。2、3被永久丢弃没有关系,nonce唯一性不要求号码连续。
归纳证明按事件分类:发号仅使用内存区间中尚未用过的next;预留把新范围接在稳定上界之后;崩溃清除内存范围,恢复从已持久化上界之后开始。三种事件都不能产生过去已用过的号。若新上界写入未确认成功,不能启用新区间;若存储损坏无法判定最新值,应停止使用该密钥。
错误变体在使用0、1之后把D恢复到0。重新加密时再次使用 balance=100、balance=900,去掉末尾16字节标签后,密文主体异或等于明文异或。它展示了一个具体保密失败,而且执行已离开旧AEAD游戏允许的nonce-respecting范围;不是在合法游戏中破解了AEAD。
推论与应用
普通原子写不阻止虚拟机快照回滚或磁盘克隆。若两份实例都恢复到同一D并继续使用同一K,仍会发出相同范围。必须由外部不回滚的代际、可靠独占或重新建立真正不同的密钥来解决;只在文件里同时保存一个可回滚epoch没有帮助。多个写者也要共享原子区间分配,或采用经证明不相交的nonce子域。
序号达到表示上限前必须换钥;更早还要遵守所用AEAD对记录数、总块数和失败验证次数的安全界。64位序号绝不意味着可安全发送