一个好的密码管理器应当能够安全地存储、同步你的用户名和密码,甚至在登录网站和应用时自动填写。这样的密码管理器,例如……Dropbox Passwords!
2020年夏季发布Dropbox Passwords时,我们必须确保用户的登录信息在他们使用的任何设备上都随时可用,而且保持最新。幸运的是,Dropbox在这方面已有经验,我们能够利用现有的同步基础设施,将用户加密后的密码信息——称为载荷(payload)——从一台设备复制到另一台。不过,在实现这个关键组件时,我们遇到了意料之外的同步问题:有时,过时的登录条目会覆盖更新、更近的修改。
最终,我们找到了建立在Dropbox既有同步工作之上的解决方案。但这个过程也让我们思考了时间本身的性质。
双向合并
Dropbox Passwords使用零知识加密。这意味着,用户密码的私有加密密钥只存储在用户的本地设备上,服务器无法解密这些密码。虽然这有利于安全,但也意味着同步与合并必须由客户端管理,无法像通常那样把服务器当作判断新旧的权威来源。
最初,同步算法使用双向合并。如果用户编辑了已有登录条目,从而修改客户端的本地载荷,客户端就执行以下步骤:
- 使用新的详细信息和当前时间更新本地载荷。
- 从服务器下载对应载荷。
- 比较本地登录条目与远程登录条目的时间戳。
- 选择较新的登录条目作为胜出版本。
下图展示了用户把密码从hunter1更新为hunter2时,可能发生的流程。
一次成功的合并与同步。理论上,这种方式很不错:旧条目会被最新版本替换。但在实践中,我们发现部分条目的同步并不正确。一位工程师发现了一个现象:旧条目竟然会压过新条目。
经过深入调查,我们找到了原因:时钟偏差。
互相冲突的时钟
考虑这样一个场景。你是一位Dropbox Passwords用户,电脑和手机都同步到同一个账户。你在手机上修改某个登录条目的备注,记录那些难记的安全问题。几分钟后,你发现其中一个问题打错了,但手机在房间另一头,于是打开电脑修正错误。更新备注并保存后,奇怪的事情发生了:你震惊地发现,最初在手机上进行的修改覆盖了刚刚在笔记本电脑上做的新修改。这是怎么回事?
回想一下,每个条目的时间戳都是客户端设置的。我们一般假设电子设备能准确表示当前时间,但事实并非总是如此。设备时间可能与真实时间不同步。原因可能是CMOS电池没电、时区设置错误,甚至是恶意软件。
在上面的例子中,手机上的登录条目因为时钟偏差而胜过电脑上的条目。如果电脑时钟比真实时间慢——无论是十分钟、十秒,还是十年——更近的修改都有可能被标记为更旧。下图展示了时钟存在偏差时,一次失败同步的可能流程。
一次失败合并的示例。注意,较新修改的时间戳反而早于稳定版本。三方合并
为了解决这个问题,我们借用了流行源码管理工具Git中的三方合并思想。当两个分支之间没有从一个分支线性合并到另一个分支的路径时,Git会使用三方合并。此时,两者具有共同祖先,但互相都不是对方的祖先。三方合并使用共同祖先和两个分支的末端版本,生成合并提交。
实际上,Dropbox桌面客户端在设备间同步文件时,早已采用了相同思想。虽然桌面客户端的冲突处理版本更先进,但基本原则一致。我们意识到,三方合并或许也能帮助这里的同步。
在我们的场景中,双向合并的主要问题是:服务器无法作为权威来源,因此没有修订历史可以记录哪个版本更早。于是,我们总要依赖时间戳判断哪个更新较新。为解决这一问题,我们引入了第三份载荷副本,称为base。现在……
- local载荷表示用户在客户端看到的内容。
- remote载荷表示Dropbox服务器中存储的内容。
- base载荷表示该客户端最近一次已同步的载荷。
现在不再简单比较local与remote的时间,而是生成local与base的差异,以及remote与base的差异。如果base和与之比较的载荷不同,我们就知道最近的修改必然来自非base载荷,因为base无法被直接编辑。
获得本地和远程差异列表后,我们就可以尝试整合修改,使三份载荷重新一致。比较差异时有两种可能结果:
- 条目只出现在其中一个差异列表中。这意味着两组差异没有冲突,双方修改都可以安全应用。
- 条目同时出现在两组差异中。这类修改被视为冲突,因为本地和远程载荷都更新了同一条目。此时,使用时间戳解决冲突:时间戳较新的修改胜出。
细心的读者会指出,这种合并过程仍受时钟偏差影响。但在正常使用中,这种情况很少发生:用户不仅需要两台时钟不同步的设备,还必须同时在这两台设备上编辑同一条目。
三方合并投入使用后,明显可以看出新增的base载荷解决了合并问题。在典型时钟偏差场景中,合并期间通常不会有冲突,因此不再需要比较时间戳。
时钟存在偏差时,一次成功的合并与同步。为未来打下稳固基础
正式可用一年后,三方合并已证明比此前的方案稳健得多。2021年陆续增加密码共享和支付卡条目等新功能时,我们尤其庆幸有这份额外稳定性。对于尝试修改共享条目的用户,双向合并问题可能会更加令人沮丧,因此我们很高兴先加固了基础,再在其上构建功能。
既然可以亲自体验,何必只读文章?安装Dropbox Passwords,让你的设备也体验一下三方合并。(此为原文发布时的产品邀请,当前可用性另行核验。)
还有一件事……
你重视密码安全和顺畅的同步体验吗?Dropbox正在招聘!无论你热爱解决难题,还是更喜欢日常修复程序缺陷,我们都在寻找充满好奇心的新工程师。Dropbox期待欢迎你的加入!访问招聘页面申请。(保留原文招聘信息。)
原文:同步密码载荷时,如何应对时钟偏差;作者:John Karabinos、Tony Xu、Andrew Hannon;日期:2022-05-17。原文及源码权利归原作者和相应权利人所有。











暂无评论内容