DH 算法是 Diffie和Hellman于1976年提出了一种的密钥交换协议。这种加密算法主要用于密钥的交换,可以在非安全信道下为双方创建通信密钥,通讯双方可以使用这个密钥进行消息的加密、解密,并且能够保证通讯的安全。

换而言之,算法希望实现这样的一个效果:

通信方A和B首先各自生成密钥DaD_aDa​和DbD_bDb​,然后通过某种计算获得各自的公钥PaP_aPa​和PbP_bPb​,接下来,A和B互相交换公钥PaP_aPa​和PbP_bPb​。现在,A持有自己的密钥DaD_aDa​和B的公钥PbP_bPb​,B持有自己的密钥DbD_bDb​和A的公钥PaP_aPa​,DaD_aDa​与PbP_bPb​、DbD_bDb​与PaP_aPa​经过某种数学运算,都能生成一个相同的加密密钥S用于通信。正在监听通信的第三方由于只得到了PaP_aPa​和PbP_bPb​,是无法计算得出密钥S的。

具体的过程如下图所示:

公钥PaP_aPa​和PbP_bPb​由函数f1f_1f1​计算得出,共享密钥由f2f_2f2​计算得出。这两个函数的破解难度直接影响到整个密钥交换算法的强度。

不妨选择函数为f2(a,b)=abf_2(a,b)=abf2​(a,b)=ab,也就是说我们需要让等式DaPb=DbPaD_aP_b=D_bP_aDa​Pb​=Db​Pa​成立(否则无法生成相同的密钥)。现在我们随便选择一个常量因子F,令函数f1(x)=F⋅xf_1(x)=F·xf1​(x)=F⋅x,则有DaFDb=DbFDaD_aFD_b=D_bFD_aDa​FDb​=Db​FDa​,等式DaPb=DbPaD_aP_b=D_bP_aDa​Pb​=Db​Pa​成立了。

现在我们得出了一个简单的密钥交换策略:双方都先约定好一个常数F,假设为100好了,然后A和B各自随机生成一个密钥,假设Da=3D_a=3Da​=3,Db=4D_b=4Db​=4,按照函数f1f1f1生成公钥Pa=300P_a=300Pa​=300,Pb=400P_b=400Pb​=400,然后互相交换。现在A知道DaD_aDa​和PbP_bPb​,一乘起来就是1200,B那边也是,Db⋅Pa=1200D_b·P_a=1200Db​⋅Pa​=1200,这个1200就是他们的共享密钥S。

如果只得知双方交换的公钥,是无法得出密钥S的,但是F被第三方得知的话,通信加密就会立刻被破坏。首先,这个常数F不能固定写在程序内,因为程序一旦发布,这个固定的常数就有暴露的风险,更糟糕的是,F暴露之后所有使用这个常数的会话都变得不安全了。而每次会话随机选择一个常数F,面临的问题则是双方如何在不安全信道交换F。

上述简单策略不能实现密钥交换的原因是算法过于简单并且可逆。若是只是简单的使用加减乘除进行多项式计算,基本都是可逆且能够快速计算出来的。因此,如何防止别人利用从公钥PaP_aPa​、PbP_bPb​根据函数f1f_1f1​进行逆向分解得出A或B的密钥,即不可逆,同时又可以让A和B根据公钥生成公共的密钥成了关键。(就算函数f1f_1f1​不出现在网络中,但在最坏的情况下函数f1f_1f1​会暴露)。

生成公钥的f1f_1f1​有两种实现方式:基于离散对数难题的最早版本的DH算法,和结合了椭圆曲线问题的加强版算法ECDH。

基于离散对数难题的DH算法

要实现不可逆的目标,其实也就是令函数f1f_1f1​没有反函数,例如f(x)=x2f(x)=x^2f(x)=x2在定义域RRR上没有反函数。当然,只是没有反函数的话强度是不够的,y=x2y=x^2y=x2中的y只有两种可能的x取值,稍微用密文试试手就知道x和-x谁才是密钥了。一个y最好对应无穷个x的值,例如y=xmodpy=x\mod py=xmodp,但是这样还不够,仍存在被暴力破解的风险。

f1f_1f1​实现如下,它利用了离散对数问题的难解性:

选择一个二元组(g,p)(g,p)(g,p),定义函数f1(x)=gxmodpf_1(x)=g^x \mod pf1​(x)=gxmodp,其中x∈(1,p)x \in (1,p)x∈(1,p)且为整数,作为公钥生成的函数。

这其中g和p都是一个常数。假设窃听者得知了公钥PaP_aPa​,想要计算DaD_aDa​的话,不妨设n∈Nn \in Nn∈N,然后有:
gDa=n⋅p+Pa→Da=log⁡g(n⋅p+Pa)g^{D_a}=n·p+P_a \rightarrow D_a=\log_{g}(n·p+P_a) gDa​=n⋅p+Pa​→Da​=logg​(n⋅p+Pa​)
想要解答上述算式存在时间上的问题,对于精心挑选的的g和p而言,没有多项式时间的经典算法可用于破解它们。

如何选择二元组(g,p)

如果并不关心算法参数的具体实现,这一节内容可以跳过。

二元组需要满足什么条件,才不会被轻易破解呢?

假设我们选择了一个二元组(2,7),不妨使用函数f1f_1f1​计算一下:
21mod7=222mod7=423mod7=124mod7=22^1\mod 7=2 \\ 2^2\mod 7=4 \\ 2^3\mod 7=1 \\ 2^4\mod 7=2 21mod7=222mod7=423mod7=124mod7=2
2xmod72^x \mod 72xmod7的值存在一个循环,这可不是什么好消息,攻击者无需遍历1~p就有可能猜出密钥!

上面的循环,我们专门用阶来定义这种概念。

阶的定义:m为正整数,若(a,m)=1(a,m)=1(a,m)=1,使得admodm=1a^d \mod m=1admodm=1成立的最小正整数d,被称为a对模m的阶,记作ordm(a)ord_m(a)ordm​(a)。(a,m)(a,m)(a,m)的含义为a与m互质。

我们可以证明,a,a2,⋯aordm(a)a,a^2,\cdots a^{ord_m(a)}a,a2,⋯aordm​(a)mod mmm的值两两不相等(或者说它们互不同余)。那么要想加强算法的强度,阶d最好应当等于m-1,这样意味着admodma^d \mod madmodm的取值范围为[1,m−1][1,m-1][1,m−1],达到了最大化。

想要达到这个目的,我们还得回答一个问题:admodma^d \mod madmodm中,对于任意一个m而言,a存在某个值,使得其阶d等于m-1吗?

要回答这个问题,需要引入欧拉函数的概念:

对于正整数n,欧拉函数φ(x)\varphi(x)φ(x)是小于n的正整数中与n互质的数的数目。

例如φ(10)=4\varphi(10)=4φ(10)=4,与它互质的数分别为1、3、7、9。而φ(7)=6\varphi(7)=6φ(7)=6,对于质因数x而言,φ(x)=x−1\varphi(x)=x-1φ(x)=x−1。

下面的欧拉定理能部分回答我们的问题:
若a,m均为正整数,(a,m)=1,则aφ(m)modm=1若a,m均为正整数,(a,m)=1,则a^{\varphi(m)}\mod m=1 若a,m均为正整数,(a,m)=1,则aφ(m)modm=1

上面的定理实际上告诉了我们a对模m的阶的最大值至多为φ(m)\varphi(m)φ(m)。例如对于模15来说,不管如何选择底数a,它的阶最大也只可能是φ(15)=8\varphi(15)=8φ(15)=8,而不可能是我们期望的最好的值14。要想达到最好的效果,模m就必须选择一个奇质数(2是质数但它太小了),这样φ(m)=m−1\varphi(m)=m-1φ(m)=m−1,才有希望取到最大的阶。

不过问题还没回答完,对于某个确定的模m(比如说7),真的存在一个数a,它的阶是φ(m)\varphi(m)φ(m)吗?请不要把这个问题和上面的欧拉定理混淆,虽然aφ(m)modm=1a^{\varphi(m)}\mod m=1aφ(m)modm=1(欧拉定理)必定成立,但是不代表值φ(m)\varphi(m)φ(m)是a的阶啊!

举一个很明显的例子,假设a=2,p=7,我们很容易得知φ(7)=6\varphi(7)=6φ(7)=6,而26mod7=12^6\mod 7=126mod7=1,欧拉定理确实是成立的,但重新再看看上面举的例子,我们发现23mod7=12^3\mod 7=123mod7=1,也就是说2对7的阶为3,并不是6!

让我们计算一下3对7的阶:
31mod7=332mod7=233mod7=634mod7=435mod7=536mod7=13^1\mod 7=3 \\ 3^2\mod 7=2 \\ 3^3\mod 7=6 \\ 3^4\mod 7=4 \\ 3^5\mod 7=5 \\ 3^6\mod 7=1 \\ 31mod7=332mod7=233mod7=634mod7=435mod7=536mod7=1
3的阶是6,也就是说对于7而言,存在一个数3的阶为φ(7)\varphi(7)φ(7)。那么如何称呼满足这种性质的数a呢?我们再给出一个原根的定义:
若a,m均为正整数,(a,m)=1,令admodm=1成立的最小正整数d,其满足d=φ(m)的话,则称a是模m的原根若a,m均为正整数,(a,m)=1,令a^d\mod m=1成立的最小正整数d,其满足d=\varphi(m)的话,则称a是模m的原根 若a,m均为正整数,(a,m)=1,令admodm=1成立的最小正整数d,其满足d=φ(m)的话,则称a是模m的原根
可以证明,若p是奇质数,则模p的原根存在,而合数就不一定了,例如15就没有原根。

根据上面的推导,选择二元组的要求呼之欲出:在(g,p)(g,p)(g,p)中,p应当是一个大质数,g应当为p的一个原根,这样一来想要计算出密钥DaD_aDa​是一件相当困难的事情。

生成共同密钥

生成共同密钥的函数f2f_2f2​应当保证两边生成的密钥都是一样的,具体实现为:
对于A:S=f2(Da,Pb)=PbDamodp对于B:S=f2(Db,Pa)=PaDbmodp对于A:S=f_2(D_a,P_b)=P_b^{D_a}\mod p\\ 对于B:S=f_2(D_b,P_a)=P_a^{D_b}\mod p 对于A:S=f2​(Da​,Pb​)=PbDa​​modp对于B:S=f2​(Db​,Pa​)=PaDb​​modp
其中p就是函数f1f_1f1​中的二元组中的p。其实我们把函数f1f_1f1​的参数扩展为两位:f(D,g)=gDmodpf(D, g)=g^D\mod pf(D,g)=gDmodp,函数f1f_1f1​和f2f_2f2​的形式是完全一致的。 我们需要证明f(Db,f(Da,g))=f(Da,f(Db,g))f(D_b,f(D_a,g))=f(D_a,f(D_b,g))f(Db​,f(Da​,g))=f(Da​,f(Db​,g))成立。以下是证明:

令t=f(D,g)=gDmodpt=f(D, g)=g^D\mod pt=f(D,g)=gDmodp,则有gD=kp+tg^D=kp+tgD=kp+t,反过来,t=gD−kpt=g^D-kpt=gD−kp,其中k是整数。既然t=f(D,g)=gD−kpt=f(D, g)=g^D-kpt=f(D,g)=gD−kp,那么有f(Da,f(Db,g))=(t)Damodp=(gDb−kp)Damodpf(D_a,f(D_b,g))=(t)^{D_a}\mod p=(g^{D_b}-kp)^{D_a}\mod pf(Da​,f(Db​,g))=(t)Da​modp=(gDb​−kp)Da​modp

根据二项式法则展开(gDb−kp)Da(g^{D_b}-kp)^{D_a}(gDb​−kp)Da​,不带有kpkpkp的项只有一个gDbDag^{D_bD_a}gDb​Da​,其他带有kpkpkp的项计算modp\mod pmodp的结果都为0,因此(gDb−kp)Damodp=gDbDamodp(g^{D_b}-kp)^{D_a}\mod p=g^{D_bD_a}\mod p(gDb​−kp)Da​modp=gDb​Da​modp基于对称性的思想,可以立刻列出f(Db,f(Da,g))=(gDa−kp)Dbmodp=gDaDbmodpf(D_b,f(D_a,g))=(g^{D_a}-kp)^{D_b}\mod p=g^{D_aD_b}\mod pf(Db​,f(Da​,g))=(gDa​−kp)Db​modp=gDa​Db​modp所以,f(Db,f(Da,g))=f(Da,f(Db,g))f(D_b,f(D_a,g))=f(D_a,f(D_b,g))f(Db​,f(Da​,g))=f(Da​,f(Db​,g))成立。

一文读懂DH密钥交换算法相关推荐

  1. 一文读懂程序化交易算法交易量化投资高频交易统计利

    转 一文读懂程序化交易.算法交易.量化投资.高频交易. 统计套利 在央行发布的<中国金融稳定报告(2016)>中,对于高频交易的解释为程序化交易的频率超过一定程度,就成为高频交易.而对程序 ...

  2. k均值聚类算法考试例题_一文读懂K-means聚类算法

    1.引言 什么是聚类?我们通常说,机器学习任务可以分为两类,一类是监督学习,一类是无监督学习.监督学习:训练集有明确标签,监督学习就是寻找问题(又称输入.特征.自变量)与标签(又称输出.目标.因变量) ...

  3. k means聚类算法_一文读懂K-means聚类算法

    1.引言 什么是聚类?我们通常说,机器学习任务可以分为两类,一类是监督学习,一类是无监督学习.监督学习:训练集有明确标签,监督学习就是寻找问题(又称输入.特征.自变量)与标签(又称输出.目标.因变量) ...

  4. 一文读懂约瑟夫环算法

    2020-05-25 20:13:40 作者 | 扬帆向海 责编 | 王晓曼 出品 | CSDN博客 问题描述 约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的 ...

  5. pca降维的基本思想_一文读懂 PCA 降维算法

    转自:chenbjin https://www.cnblogs.com/chenbjin/p/4200790.html 主成分分析(PCA)是一种基于变量协方差矩阵对数据进行压缩降维.去噪的有效方法, ...

  6. 一文读懂约瑟夫环算法 | 原力计划

    作者 | 扬帆向海 责编 | 王晓曼 出品 | CSDN博客 问题描述 约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为约瑟夫环.又称&q ...

  7. 一文读懂朴素贝叶斯分类算法

    因为毕业论文是和贝叶斯理论相关的内容,今天恰巧看到一篇朴素贝叶斯分类算法的文章,写的非常通俗易懂,再结合另外一篇CNN的文章,在这里梳理一下,来帮助自己的理解. 朴素贝叶斯算法是基于朴素贝叶斯定理的一 ...

  8. 技术原创|一文读懂图遍历算法以及图计算应用

    为解决大规模计算和海量数据处理问题,Google 在 2010 年提出了图计算模型 Pregel.随后又陆续出现了.GraphLab.GraphChi等典型图计算系统. 图计算是人工智能的一个使能技术 ...

  9. C_一文读懂推荐系统知识体系-上(概念、结构、算法)

    本文主要阐述: 推荐系统的3个W 推荐系统的结构 推荐引擎算法 浏览后四章的内容请见下篇. 1. 推荐系统的3个W 1.1 是什么(What is it?) 推荐系统就是根据用户的历史行为.社交关系. ...

  10. 从实验室走向大众,一文读懂Nanopore测序技术的发展及应用

    关键词/Nanopore测序技术    文/基因慧 随着基因测序技术不断突破,二代测序的发展也将基因检测成本大幅降低.理想的测序方法,是对原始DNA模板进行直接.准确的测序,消除PCR扩增带来的偏差, ...

最新文章

  1. 个人作业1 四则运算题目生成程序
  2. python语言入门详解-Python unittest详解一(基础入门)
  3. anaconda双版本完美并存
  4. java调用存储过程 sql server_Java中调用SQL Server存储过程示例
  5. 【转】DICOM图像像素值、灰度值与CT值!!!!!
  6. 计算机网络 --- 数据链路层CSMA/CA协议
  7. docker 本地部署 mysql_Docker 部署Mysql 服务和Redis 服务的方法
  8. 访问linux端口失败_教你如何配置Linux服务器防火墙端口规则
  9. 感谢大家对课程的关注和喜爱
  10. format mla_MLA-Format-MLA格式
  11. java 调用打印机打印PDF文件
  12. win10系统迁移到新的硬盘
  13. Nexmoe 博客主题的设计理念
  14. CSAPP datalab
  15. 微信小程序获取用户收货地址与指纹验证接口(安卓和iphone)
  16. ossec支持mysql数据库_开源入侵检测工具ossec安装配置(HIDS)
  17. 设置苹果电脑vsode在新窗口中打开文件
  18. Bitly野心彰显,发布实时热门链接引擎Realtime
  19. Python生成二维码脚本
  20. nvm use不生效

热门文章

  1. CopyU!v2 已经收录到腾讯软件管家!
  2. PHP简约聚合ZB盒子程序源码
  3. 华为云计算hcip证书有效期_华为云计算容器HCIP V1.0认证
  4. linux opendir路径_Linux下目录文件的操作(opendir,readdir,closedir) 以及DIR,dirent,stat等结构体详解...
  5. 线程创建的三种方式和线程池创建的四种方式
  6. unity打开内嵌游戏网页
  7. 左耳朵耗子:996不是福气,但努力就会成功么?
  8. 激光打标程序 c语言,激光打标机 - 20160516labview - 源码下载|Windows编程|其他小程序|源代码 - 源码中国...
  9. 千月影视全新改版影视app系统-支持投屏-二开美化版
  10. 液晶驱动原理 c语言,基于STM8S的LCD驱动电路和LCD显示原理分析