每迭代一次(也可以说棘轮步进一次),就会生成新的消息密钥 。
由于 KDF 算法的单向性,通过这条消息的密钥无法倒推出上一条消息密钥,这就保证了密钥的前向安全 。但是如果 KDF 中的盐被掌握,那么它就可以按照这种算法计算出以后所有的消息密钥 。
为了保证后向安全,就要设计一种方法,使每次迭代时引入的盐是随机的,从而保证每次的消息密钥是不可以向后推算的 。
由前面介绍的 DH 算法得知:两对密钥对可以通过 DH 协议生成一个安全的协商密钥,如果更换其中一个密钥对,新的协商密钥也会变化 。
根据这个方法:我们可以设计出一个安全更新盐的方法 。我们在证书服务器增加一个临时公钥证书,这个临时证书是按照接收双方标识构建的临时公钥对,即每个人的每个单人会话都具备一个临时公钥 。每进行一个消息轮回,就更新一次己方的临时公钥,同时根据另外一方的临时公钥和己方的私钥进行协商,并将协商出的密钥作为盐,使得 KDF 棘轮算法生成的消息密钥具有后向安全性 。
在初始时我们无法预测出每个人所有的新二人会话:那么我们就可以规定创建新的二人会话时,发起方首先生成一个新的临时 DH 公私钥对,并向服务器上传自己的临时 DH 公钥;其次发送方用接收方公布的长期公钥与自己的临时私钥协商出密钥作为消息加密的密钥,对消息进行加密;最后接收方首次接收到消息后用自己的长期公钥和发送方的临时私钥计算得出消息密钥,并在首次回复消息时生成临时公私钥,同时上传临时公钥 。
问题是:如果接收端不在线,而发送端每条消息都去更新己方的临时公钥证书,就会导致发出去的这些消息,在接收端上线并收取后无法被正常解密 。
为了解决这个问题,我们需要规定:只有在发出消息并得到对方回复后才更新临时证书,若对方不回复消息则不去更新临时证书 。接收端能回复消息就表示其已经上线并接收完消息,这样就可以保证离线消息或者消息乱序也可以被对方正常解析 。这种方法就是双棘轮算法中的另外一个 DH 棘轮 。
6.5 更安全的密钥交换协议—— X3DH
对比最初的方案,为了满足消息的前向安全和后向安全,我们增加了双棘轮算法,在原基础方案上为每个人增加了一组会话级别临时 DH 密钥,每个人都拥有一个长期密钥和一组临时密钥 。
但是:由于长期密钥无法被更换,所以方案依然存在着安全隐患 。
因此:Signal protocol 设计了一种更为复杂和安全的 DH 密钥交换过程,称之为 X3DH(即 DH 协议的 3 倍扩展版) 。
在 X3DH 协议里,每个人都要创建 3 种密钥对,分别如下:
- 1)身份密钥对(Identity Key Pair):一个长期的符合 DH 协议的密钥对,用户注册时创建,与用户身份绑定;
- 2)已签名的预共享密钥(Signed Pre Key):一个中期的符合 DH 协议的密钥对,用户注册时创建,由身份密钥签名,并定期进行轮换,此密钥可能是为了保护身份密钥不被泄露;
- 3)一次性预共享密钥(One-Time Pre Keys):一次性使用的 Curve25519 密钥对队列,安装时生成,不足时补充 。
所有人都要将这 3 种密钥对的公钥上传到服务器上,以便其他人发起会话时使用 。
假如 Alice 要给 Bob 发送消息,首先要和 Bob 确定消息密钥,流程大致如下:
- 1)Alice 要创建一个临时密钥对(ephemeral key),我们设成 EPK-A,此密钥对是为了后面棘轮算法准备,在此处作用不大;
- 2)Alice 从服务器获取 Bob 的三种密钥对的公钥:身份密钥对IPK-B、已签名的预共享密钥 SPK-B、一次性预共享密钥 OPK-B;
- 3)Alice 开始使用 DH 协议计算协商密钥,要引入参数包括:自己创建的两个密钥对的私钥,以及 Bob 的三个公钥 。然后用类似排列组合的方式,将自己的私钥与对方的公钥分别带入 DH 算法计算 。
DH1 = DH(IPK-A, SPK-B)
DH2 = DH(EPK-A, IPK-B)
DH3 = DH(EPK-A, SPK-B)
DH4 = DH(IPK-A, OPK-B)
如图所示:
文章插图
然后将计算得到的四个值,前后连接起来,就得到了初始密钥,如下:
DH = DH1 || DH2 || DH3 || DH4
推荐阅读
- 受损系统修复的小方法一
- Win10系统更新后死机怎么办?
- Linux 系统自动化部署系统
- Linux操作系统与命令详解——Ice命令
- 胆管支架术后不良反应
- 恢复出厂设置都不保险!旧手机这样处理更安全
- 如何搜索 WhatsApp 聊天消息
- 智能汽车事故频发,辅助驾驶系统“背锅”?
- 苹果|黑客可全面控制 苹果曝出严重安全漏洞!这项更新建议所有人升级
- 让Win11系统更好用的几个设置
