新的需求

在之前的章节中,Alice 和 Bob 在进行加密通信之前,他们首先需要面对面的共享那个用于加解密的密匙。但是,如果 Alice 和 Bob 无法面对面的交换密匙,将会面临什么问题?

随着计算机网络的普及,人们之间的交流不再受到的地理位置的限制。如果 Alice 和 Bob 之间需要通过计算机网络去进行一些私密消息的传递时,他们就需要将信息加密。于是他们就会在网络通信时首先向对方发送本次通信的密匙,然后发送加密的内容。但是,他们之间总是存在一个窃听者 Eve,他将 Alice 和 Bob 之间的网络通信截取并拷贝下来,然后原封不动的发给另一方。通过这中方式,Eve 就会得到 Alice 和 Bob 之间的密匙,以及全部的加密消息,当然因为有了密匙,他也轻而易举的窃取了全部的通信内容。那么,有没有一种密匙交换方式,可以使得 Alice 和 Bob 在 Eve 的窃听下协商出一个不被 Eve 获知的通信密匙呢?

Diffie-hellman 密匙交换

在 1976 年,Whitfield Diffie 和 Martin Hellman 一起发明了一个让人叫绝的方式,被称为 “迪菲-赫尔曼密钥交换 Diffie–Hellman key exchange 简称 D-H”。D-H 是基于模运算的一个算法。所以首先我们看下什么是模运算。

比如,现在我们有一个圆形的时钟,我们注意到时钟上面的小时刻度将这个时钟的周长分成了 12 个等份,我们简称这个等份为 小时刻度周长等份。然后我们手上有一根绳子,绳子的长度为 15 倍于小时刻度周长等份。现在我们做一件事,将绳子的一头放在时钟的 0 刻度位置(或者 12 刻度),然后顺时针的将绳子沿着时钟的边缘进行一圈一圈的环绕。最后我们会发现绳子的另一头停在了刻度 3 上。简化成一个数学式子就是 15 mod 12 = 3 ,它表示 15 对 12 取模后剩余 3。

我们发现模运算有一个特点,就是对一个数求模,可以容易的得到其求模后的结果。但是如果反过来想获取原本的数却很难。比如 2187 mod 7 = 31594323 mod 7 = 3 等等,如果知道了结果 3,和模 7,无法准确得知原本的数。

接下来,我们看看在使用 D-H 密匙交换方式时,Alice 和 Bob 之间是如何协商出通信密匙的:

  1. 首先 Alice 先要随机选择两个数 a,n 作为模运算的基础,然后再次随机出一个数 x
  2. 然后 Alice 通过一个运算生成一个数 p,p 的运算方式为:
p = a^x mod n
复制代码
  1. 然后 Alice 把 p、a、和 n 告诉了 Bob,当然,Eve 也知道了这些内容
  2. 接着, Bob 随机选择一个数 y,并通过下面的运算生成一个数 q:
q = a^y mod n
复制代码

在 q 生成了之后,Bob 将其告诉了 Alice,当然,Eve 也得知了 q 5. 现在,Alice 和 Bob 开始生成密匙

// Alice
key = q^x mod n// Bob
key = p^y mod n
复制代码

通过上面的运算,Alice 和 Bob 生成了他们之间的密匙。

现在,你可能很疑惑,那就是为什么经过这一系列的运算后,Alice 和 Bob 之间生成了一把 Eve 不知道的密匙。

我们先来看看 Alice,她接收到了 Bob 传过来的公开信息 q:

q = a^y mod n               1)
复制代码

之后,为了得到密匙,她进行了下面的操作:

q^x mod n                   2)
复制代码

那么将 1) 中的 q 带入到 2) 中的式子,替换 2) 中的 q,Alice 生成密匙的操作等价于:

(a^y mod n)^x mod n         3)
复制代码

再来看看 Bob,他接收到了 Alice 传来的公开信息 p,为了生成密匙,他做了下面的操作:

p^y mod n              4)
复制代码

那么我们看看 p 是什么,它是由 Alice 这样生成的:

p = a^x mod n          5)
复制代码

这次,我们将 5) 带入到 4) 中,替换 4) 中的 p,然后我们发现 Bob 的操作等价于

(a^x mod n)^y mod n    6)
复制代码

现在,我们如果可以证明 3) 和 6) 是等价的话,就可以说明这种方式是可以工作的。

开始求证

上文中,我们通过使用一个绳子沿着时钟的边缘绕圈的例子,对求模运算有了一个形象的认识。现在,如果需要操作一根长度为 136 倍于小时刻度周长等份的绳子的话,你已经知道该如何做了 - 就是将绳子的一头放在 0 刻度,沿着时钟边缘不断地绕圈,看绳子另一头最终落在哪个刻度上。

现在,尝试以相似的方式去理解运算(100+36) mod 12 。你可以想象成,在你准备对一个长度是 136 倍于小时刻度周长等份的绳子进行绕圈之前,绳子不小心断成了两段,一段长度为 100 倍于小时刻度周长等份、另一段长度为 36 倍于小时刻度周长等份(下面就简称 “100 长度”“36 长度”)。

为了完成工作,你先将 100 长度的绳子的一头放在 0 刻度,然后开始沿着时钟边缘进行绕圈,在这个 100 长度的绳子绕完之后,绳子的另一头应该落在某个刻度上,我们使用 (100 mod 12) 去表示这个刻度。然后,你拿起另外一段 36 长度的绳子,也将它的一头放在 0 刻度,开始对时钟进行绕圈,绕完之后,绳子的另一头也落在了某个刻度上,我们使用 (36 mod 12) 去表示这个刻度。最后你将 100 mod 12 加上了 36 mod 12

为什么可以相加? 之前,我们将 36 长度的绳子的一头放在的 0 刻度,通过让绳子沿着时钟边缘不断地顺时针绕圈,使得最终绳子的另一头会落在时钟上的某一个刻度上,我使用 36 mod 12 去表示这个刻度。我们换一个角度,36 mod 12 其实也表示了一个顺时针的偏移量,你可以想象一下,不论起始刻度选在哪里,最终绳子另一头落下的刻度和起始刻度之间总会有一个 36 mod 12 的偏移量。当我们绕完了 100 长度的绳子时,我们知道了它的终点落在了 100 mod 12 这个刻度上,于是,我们拿起 36 长度的绳子,接着 100 长度的绳子的终点继续绕圈。站在偏移量的角度,“将 36 长度的绳子的一头放在 100 长度绳子结束的刻度上,然后让它继续沿着时钟边缘绕圈” 就可以看成是 “在 100 长度绳子结束的刻度上又顺时针偏移了 36 mod 12

所以我们可以让 100 mod 12 加上 36 mod 12 。不过还有一点需要注意,就是在 100 mod 12 的刻度上再顺时针偏移 36 mod 12 的话,可能会超过 0 刻度又开始新的一个绕圈。所以,100 mod 12 加上 36 mod 12 的结果还需要再 mod 12。所以完整的表示就是 (100 mod 12 + 36 mod 12) mod 12

通过这个形象的例子,我们得出一个模运算的加法规律:

(a+b) mod p = (a mod p + b mod p) mod P
复制代码

我们可以通过这个加法规律衍生出一个乘法规律:

(a*b) mod p = (a mod p * b mod p) mod p
复制代码

下面是关于这个乘法规律的证明:

证明:(a*b) mod p = (a mod p * b mod p) mod p, a、b、p ∈ 正整数∵  对于正整数 a,等式 a = k1*p + r1 一定成立对于正整数 b,等式 b = k2*p + r2 一定成立∴   a*b = (k1*p + r1 ) * (k2*p + r2)= k1*k2*p^2 + k1*p*r2 + r1*k2*p + r1*r2∵  (a+b) mod p = (a mod p + b mod p) mod p∴  (a*b) mod p = (k1*k2*p^2 + k1*p*r2 + r1*k2*p + r1*r2) mod p= (k1*k2*p^2 mod p + k1*p*r2 mod p + r1*k2*p mod p + r1*r2 mod p) mod p= (0 + 0 + 0 + r1*r2 mod p) mod p= (r1*r2 mod p) mod p= r1*r2 mod p∵  r1 = a mod p, r2 = b mod p∴ (a*b) mod p = (a mod p * b mod p) mod p得证
复制代码

那么,(a^b) mod p 有什么变换规律呢?因为 a^b = a*a*a*a...*a 一共是 ba 相乘。那么根据上面的乘法规律 (a^b) mod p 其实就是:

(a*a*a*a...*a) mod p = (a mod p * a mod p * a mod p ... * a mod p) mod p
复制代码

于是就得出了乘方的规律:

(a^b) mod p = (a mod p)^b mod p
复制代码

那么我就开始证明,为什么 Alice 生成密匙的操作与 Bob 生成密匙的操作会得到相同的结果,其实也就是证明上面的 3) 与 6) 等价,即:

(a^y mod n)^x mod n = (a^x mod n)^y mod n   10)
复制代码

首先我们结合刚得到的乘方公式,看下 10) 等式的左边:

rule: (a^b) mod p = (a mod p)^b mod p
left:             (a^y mod n)^x mod n
通过这样对齐,我们可以将 left 中的 a^y 看做一个整体,于是 left 就可以变换为:a^y*x mod n
复制代码

同样的,对于 10) 等式的右边:

a^x*y mod n
复制代码

于是我们发现,左右两边的等式是相同,因而 Alice 和 Bob 可以得到相同的结果。

繁琐的回报

到目前为止 Alice 和 Bob 之间为了协商出一个不被 Eve 获知的密匙可谓是费尽周折。那么,这么做有什么用吗?

首先,我们看看一直在窃听的 Eve 手上有了哪些信息:p,q,a,n 。

然后我们知道,对于密匙生成方式实际就是 a^x*y mod n。在这个生成密匙的式子中,Eve 只直接知道了 a 和 n,对于 x 和 y 他并没有直接获取到。当然,他也获取了 x 和 y 的相关信息,就是 p = a^x mod nq = a^y mod n。于是他只有通过两条式子去逆推出 x 和 y。

如何逆推呢?根据 p = a^x mod n,可以转换成 a^x = k*n + p,已知 a,n,p,通过不断的调整 k 算出可能的 x,同理再不断的算出可能的 y,将它们相乘再配合实际的密匙生成式子 key = a^x*y mod n 猜测所有可能的 key。

使加密更加牢固

回顾一下 Alice 是怎么生成 p 的?

// Alice
p = a^x mod n
复制代码

我们选几组不同的 a 和 n ,然后不断的调整 x 的大小,看看 p 有怎样的变化:

// 在浏览器控制台中运行
var test = function (a, n, x) {var unique = {}, out = [], p;for (var i = 1; i < x; i++) {p = Math.pow(a, i) % n;out.push(p);if (unique[p] === true) continue;unique[p] = true;}console.log("Output: ", out.join(', '));console.log("count: ", out.length);console.log("%c------------------------------------------------", "color:blue");console.log("Unique:", Object.keys(unique));console.log("count: ", out.length);console.log("%c================================================", "color:red")
};
复制代码
// test(4, 10, 100);
Output:  4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4
count:  99
------------------------------------------------
Unique: ["4", "6"]
count:  99
================================================
复制代码
// test(3, 10, 100);
Output:  3, 9, 7, 1, 3, 9, 7, 1, 3, 9, 7, 1, 3, 9, 7, 1, 3, 9, 7, 1, 3, 9, 7, 1, 3, 9, 7, 1, 3, 9, 7, 1, 3, 8, 4, 6, 6, 0, 6, 8, 2, 6, 6, 4, 2, 4, 0, 8, 8, 4, 2, 0, 4, 8, 8, 0, 4, 2, 4, 0, 2, 4, 4, 0, 2, 8, 4, 6, 2, 8, 4, 0, 8, 6, 6, 0, 4, 8, 2, 8, 2, 8, 0, 6, 8, 2, 8, 4, 0, 6, 2, 6, 0, 0, 0, 2, 6, 4, 0
count:  99
------------------------------------------------
Unique: ["0", "1", "2", "3", "4", "6", "7", "8", "9"]
count:  99
================================================
复制代码
test(3, 11, 100);
Output:  3, 9, 5, 4, 1, 3, 9, 5, 4, 1, 3, 9, 5, 4, 1, 3, 9, 5, 4, 1, 3, 9, 5, 4, 1, 3, 9, 5, 4, 1, 3, 9, 5, 3, 9, 7, 0, 4, 4, 1, 5, 4, 8, 0, 0, 6, 5, 1, 9, 5, 4, 9, 6, 0, 9, 3, 0, 0, 6, 5, 7, 3, 2, 2, 1, 1, 3, 3, 0, 7, 10, 6, 4, 4, 2, 0, 8, 1, 5, 1, 10, 4, 9, 6, 7, 9, 4, 1, 10, 7, 0, 0, 8, 2, 6, 1, 3, 5, 1
count:  99
------------------------------------------------
Unique: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
count:  99
================================================
复制代码

在上面的输出中,我们发现对于式子 p = a^x mod n 来说,当 (a, n) = 1 (读作 a 与 n 互素)时,不断地调整 x,对应的 p 值是 0~n 之间的随机整数。所以说,为了确保 p 的密匙空间足够大,我们在随机选择 a 和 n 时,要确保它们是互素的。在实际操作中,为了简化操作,我们直接随机选择素数的 a 和 素数的 n,这样就可以省略判断 a 和 n 互素的步骤。

至此,我们对 D-H 方法的作用以及原理有了简单的认识。

Diffie-hellman 密匙交换相关推荐

  1. 隐私计算加密技术基础系列-Diffie–Hellman key exchange

    1 密码学 1.1 背景 隐私计算(Privacy-preserving computation)是指在保证数据提供方不泄露原始数据的前提下,对数据进行分析计算的一系列信息技术,保障数据在流通与融合过 ...

  2. Diffie Hellman密钥交换

    In short, the Diffie Hellman is a widely used technique for securely sending a symmetric encryption ...

  3. 安装 ssh 的公开密匙到 iPhone 上

    1). 在Mac的终端上产生密匙 ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to sa ...

  4. Git创建ssh密匙时报错Too many arguments解决方法

    Git创建ssh密匙时报错Too many arguments解决方法 参考文章: (1)Git创建ssh密匙时报错Too many arguments解决方法 (2)https://www.cnbl ...

  5. xor java_java基于密匙的xor加解密

    package iminto.util.common; import java.io.IOException; import java.security.NoSuchAlgorithmExceptio ...

  6. SELINUX导致的SSH密匙无法创建和访问的问题

    故障现象: 执行生成密匙命令时提示: #ssh-keygen -t dsa ...... open /root/.ssh/id_dsa failed: Permission denied. Savin ...

  7. 带密匙的php加密解密示例分享

    <?phpheader("content-type:text/html;charset=utf-8");$id = "http://www.jb51.net&quo ...

  8. 谷歌浏览器安卓_用谷歌服务更安全了,安卓手机可充当物理安全密匙

    4月11日消息,据The Verge报道,谷歌今天宣布,任何运行Android 7或更高版本操作系统的手机,现在都可以充当两步验证机制的物理安全密钥.这意味着,与谷歌当前提供的其他几种两步验证方法相比 ...

  9. php 密匙加密解密,带密匙的php加密解密示例分享

    这篇文章主要介绍了php加密解密示例,大家参考使用吧 复制代码 代码如下: /************************************************************* ...

  10. Microsoft Office Home and Student 2007 密匙

    Microsoft Office Home and Student 2007 密匙 Microsoft Office Home and Student 2007产品密匙 DDY79-433JV-2RX ...

最新文章

  1. cf792b循环链表
  2. R语言文件下载:谁来帮我把这个128个音频下载一下
  3. 数据可视化组队学习:《Task02 - 艺术画笔见乾坤》笔记
  4. mysql加上判断_在mysql中where加if判断
  5. BP神经网络分类实战项目(深度学习笔记)原创!基础篇||PCA降维、反向传播公式、梯度下降、标准化、倾斜样本处理、独热编码、Adam优化算法、权值初始化、F1-Score、ROC、模型可视化
  6. fckeditor组件使用---配置FCKeditor,以及使用方法2
  7. PHP函数和MySQL数据库
  8. python编程代码画画_分享给大家几段有趣的代码,学会python画画可以不用自己动手啦...
  9. 正则表达式与有限自动机
  10. ios越狱改设备id_为什么要越狱iOS设备
  11. Pandas:分组级的运算和转换--transform和apply
  12. Nginx反向代理https配置解决方案
  13. pandas支持读取哪些类型文件_Pandas教程: 读取Excel文件
  14. Hive自定义函数(字母大小写转换)
  15. 百城百店 宝瓷林.北京SKP商场品牌店开业
  16. Linux_vi/vim快捷键
  17. CRMEBV4小程序H5页面端宝贝列表分享海报以及会员中心分销推广不显示的常见问题解决
  18. 联想计算机不能进入系统桌面,win10电脑开机后进不了系统桌面只有联想logo
  19. 12864多级菜单实现方法
  20. 去除WinRAR 5.01(32位) NAG窗口

热门文章

  1. python用smtp发邮件怎么抄送_邮件未发送给抄送中的人
  2. html+css个人简历/网页界面
  3. 仿苹果响应式官网(含代码!)
  4. 【渝粤题库】陕西师范大学209020 史记研究 作业(专升本)
  5. MATLAB 绘图笔记——绘制两端尖角colorbar
  6. phpmyadmin linux 升级,phpMyAdmin 4.9.2发布下载,附主要更新内容介绍
  7. 关于 Tortoise git 工具的使用
  8. 4个基本不等式的公式高中_基本不等式公式四个
  9. dimens文件生成器使用方法
  10. Android Studio 手动创建活动(Activity) 第一行代码 第二章