blog/changepassphrase.md

1.8 KiB
Raw Blame History

##更新密钥 密钥托管 设计笔记

服务器以HTTP接口提供密钥托管服务其中PUT方法是更新密钥通常用于修改口令。维护状态会引入额外的复杂性因此希望是一次性的调用。

浏览器通过GET方法获得加密的密钥然后用户输入口令在浏览器直接加盐取哈希解密。这时候规定一段特定内容作为验证码用户对验证码进行数字签名与更新的密钥PUT给服务器。我们需要讨论的是这个验证码的设计。

我们必须假设网络通信是:

  • 可以监听的:攻击者可以获得这特定内容及其数字签名。
  • 可以截断的:服务器和浏览器发给对方的内容,接收方不能收到。
  • 可以篡改的:服务器和浏览器发给对方的内容,接收前会被改变。

假设监听是永久的,攻击者不能永久地截断和篡改。在这种情况下,攻击者无法通过更新密钥伪造用户的数字签名。

一次性的调用,要求这验证码是无需协商的,浏览器端就可以生成,而服务器端可以验证。如果接受任意内容作为验证码,用户在日常使用中提供的数字签名,会被攻击者用作验证码去更换密钥。

在简单对比各种选择后以整个新密钥yaml结构作为验证码是目前最佳方案。

  • name
  • id
  • email
  • salt
  • pubkey公钥
  • secpey私钥

首先,它是服务器和用户浏览器无需额外通信就可以达成一致的。其次,日常应用不会对同类数据进行数字签名,攻击者无从提前准备。如果攻击者获得更新信息并截断通信,也无法伪造另一套密钥发给服务器。一旦用户重新与服务器联通,可以再次发送正确的更新信息,攻击者除了截断通信外没有获得额外好处。