DH密钥交换算法

1 篇文章 0 订阅
Diffie-Hellman密钥交换协议由Whitfield Diffie与Martin Hellman提出,用于在不直接传递密钥的情况下安全交换密钥。该算法基于数学理论,确保交换过程中传输的信息无法推算出最终密钥。Go语言示例展示了其工作原理,对比RSA,DH主要用于密钥协商,而非加密解密,且DH交换的密钥通常用于对称加密算法。
摘要由CSDN通过智能技术生成

 

简介(百度百科)

Whitfield Diffie与Martin Hellman在1976年提出了一个奇妙的密钥交换协议,称为Diffie-Hellman密钥交换协议/算法(Diffie-Hellman Key Exchange/Agreement Algorithm)。这个机制的巧妙在于需要安全通信的双方可以用这个方法确定对称密钥。然后可以用这个密钥进行加密和解密。但是注意,这个密钥交换协议/算法只能用于密钥的交换,而不能进行消息的加密和解密。双方确定要用的密钥后,要使用其他对称密钥操作加密算法实现加密和解密消息。

实现

DH算法解决了密钥在双方不直接传递密钥的情况下完成密钥交换,这个神奇的交换原理完全由数学理论支持。我们来看DH算法交换密钥的步骤。假设甲乙双方需要传递密钥,他们之间可以这么做:

  1. 甲首选选择一个素数p,例如509,底数g,任选,例如5,随机数a,例如123,然后计算A=g^a mod p,结果是215,然后,甲发送p=509g=5A=215给乙;
  2. 乙方收到后,也选择一个随机数b,例如,456,然后计算B=g^b mod p,结果是181,乙再同时计算SA=A^b mod p,结果是121;
  3. 乙把计算的B=181发给甲,甲计算SB=B^a mod p的余数,计算结果与乙算出的结果一样,都是121。

所以最终双方协商出的密钥SA=SB是121。注意到这个密钥SA或SB并没有在网络上传输。而通过网络传输的pgAB是无法推算出SA、SB的,因为实际算法选择的素数是非常大的例如(7000487615661733、5925845745820835 等)。所以,更确切地说,DH算法是一个密钥协商算法,双方最终协商出一个共同的密钥,而这个密钥不会通过网络传输。

图例

设想这样一个场景,Alice(A)和Bob(B),他们想在不见面的情况下秘密约定出一种颜色,但他们互相沟通的信息都会被公开,应该怎么办呢?

 Alice Bob
私密信息公开信息公开信息私密信息
A和B首先约定好公开的一种颜色,比如黄色   
A,B各自挑选出一种私密的颜色,比如橙色和兰色   
A,B各自将两种颜色混合起来 
     
双方交换混合后的颜色   
A,B各自将自己的私密颜色再次混入得到的颜色中   
现在A,B得到了一种相同的颜色,这种颜色是由一份黄色、一份橙色、一份兰色混合而来,但外界无法得知   

go示例

go
package game

import (
  "fmt"
  "math/big"
  "testing"
)

// DH密钥协商算法
func TestDh(t *testing.T) {
  // p为16位质数
  p := big.NewInt(7000487615661733)
  g := big.NewInt(5925845745820835)

  // EXP(a, b, c) = (a ** b) % c
  // 服务器生成A发给客户端
  a := big.NewInt(123)
  A := big.NewInt(0).Exp(g, a, p)
  fmt.Println("A ", A)

  // 客户端生成B发给服务器
  b := big.NewInt(456)
  B := big.NewInt(0).Exp(g, b, p)
  fmt.Println("B ", B)

  // 如果收到的客户端B为一个任意数,则双方协商的密钥将不一致,双方也将无法解密出正确数据
  //B.SetString("123", 0)

  // 服务器拿到客户端的B,生成密钥SA
  SA := big.NewInt(0).Exp(B, a, p)
  fmt.Println("SA", SA)

  // 客户端拿到服务器的A,生成密钥SB
  SB := big.NewInt(0).Exp(A, b, p)
  fmt.Println("SB", SB)

  if SA.String() != SB.String() {
    fmt.Println("SA != SB, 密钥协商失败!")
    return
  }

  // 最终SA=SB,完成密钥协商
  key := []byte(SA.String())
  // 将16位key拼接成32位key
  key = append(key, key...)

  // 先AES加密
  encrypt,_ := AesEncrypt([]byte("123456"), key)
  // 再异或运算加密
  for i,item := range encrypt {
    encrypt[i] = item ^ 28
  }
  fmt.Println("encrypt:", encrypt)

  // 先异或运算解密
  for i,item := range encrypt {
    encrypt[i] = item ^ 28
  }
  // 再AES解密
  decrypt,_ := AesDecrypt(encrypt, key)
  fmt.Println("decrypt:", string(decrypt))

}

秘密在于,颜色混合是一种“不可逆”的操作,当双方交换颜色时,尽管我们知道他们交换的颜色都是由一份黄色和另一份其他颜色混合得到的,但我们还是无法或者很难得到他们的私密颜色。而DH秘钥交换的原理非常相似,也是利用了数学上的一个“不可逆”的运算,就是离散对数(Discrete logarithm

DH密钥协商和RSA加密算法的比较

首先说明:RSA和DH实际上根本不是一回事

RSA是公钥加密算法,也就是非对称密码算法,一般情况下的使用流程是这样的:

  • A通过B公开的公钥加密信息,加密信息,发送加密后的信息给B,B通过自己的私钥进行解密;
  • B如果想给A发送消息,就先获取A公开的密钥,加密信息,发送加密后的信息给A,A通过自己的私钥进行解密。

DH是密钥交换协议,一般情况下的使用流程是这样的:

  • A和B通过DH协议获得了同一个密钥;
  • A然后用这个密钥采用其他的对称密码算法如DES AES对通信进行加密解密,传递给B;
  • B使用同样的密钥采用其他的对称密码算法如DES AES对通信进行加密解密,传递给A。

总结一下,区别主要是:

  1. RSA是用来加密解密的,DH是用来协商创造密钥的,
  2. RSA可以用来传递信息,DH是用来传递密钥的,想要传递信息还需要借助别的加密方式。
  3. 使用RSA进行信息传输是非对称密码体系,使用DH进行密钥交换的下一步使用的一般是对称的密码体系
  4. 使用RSA加密和解密所使用的密钥是不一样的,前者叫公钥后者叫私钥,公钥用于加密私钥用于解密,并且不可逆向,也就是不能用私钥加密公钥解密。如果A和B想进行通信的话,需要两套(4个)密钥。而DH交换得到的密钥则一般是用于对称加密的,也就是加密和加密使用的是同一个密码,进行通信只需要一个密钥即可。

然后解释一下,如何用RSA做密钥协商(密钥交换)

实际上可以模拟成下面的情况:A想和B进行密钥交换,获得一个新的密钥,于是A就通过B的公钥加密了一个密钥K(此处的密钥相当于原文),然后将生成的密文发给B。B接到了这个密文之后使用自己的私钥解密获得密钥K。于是双方就可以愉快的使用这个K来进行后面的加密了~

这就是最简单的RSA密钥交换模型了。实际上考虑到前面提到的中间人攻击的问题,因此A往往需要同时加上自己的身份认证信息。同时有些复杂点儿的情况下可能还需要B通过A的公钥发送一系列的确认信息。
因此RSA做密钥协商(密钥交换)时和DH的从原理上而言是有着非常大的差距的。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值