1. 概述
Diffie-Hellman密钥协商算法主要解决秘钥配送问题,本身并非用来加密用的;该算法其背后有对应数学理论做支撑,简单来讲就是构造一个复杂的计算难题,使得对该问题的求解在现实的时间内无法快速有效的求解(computationally infeasible )。
理解Diffie-Hellman密钥协商的原理并不困难,只需要一点数论方面的知识既可以理解,主要会用到简单的 模算术运算、本原根、费马小定理、离散对数 等基础数论的知识。在现代密码学中的基础数论知识梳理中已经对这些知识做了必要的总结。
2. 从何而来
DH密钥协商算法在1976年在Whitfield Diffie和Martin Hellman两人合著的论文New Directions in Cryptography(Section Ⅲ PUBLIC KEY CRYPTOGRAPHY)中被作为一种公开秘钥分发系统(public key distribution system)被提出来。原文的叙述过程比较简单,但基本阐述了算法的原理以及其可行性。
在该论文中实际上提出了一些在当时很有创新性的思想。原论文重点讨论两个话题:
(1)在公网通道上如何进行安全的秘钥分派。
(2)认证(可以细分为消息认证和用户认证)。
为了解决第一个问题,原文提出两种方法:公钥加密系统(public key cryptosystem)和秘钥分发系统(public key distribution system)。对于公钥加密系统,原文只是勾画了一种比较抽象的公钥加密系统的概念模型,重点是加解密采用不同的秘钥,并总结了该系统应该满足的一些特性,相当于是一种思想实验,并没有给出具体的算法实现途径,但这在当时应该来说已经足够吸引人。后来RSA三人组(Ron Rivest、Adi Shamir 和 Leonard Adleman)受此启发,经过许多轮失败的尝试后,于第二年在论文A Method for Obtaining Digital Signatures and Public-Key Cryptosystems中提出了切实可行且很具体的公钥加密算法--RSA公钥加密算法。而对于秘钥分发系统,就是本文的DH秘钥协商算法。
为了解决第二个问题,原文通过单向函数(one-way function)来解决,这就是单向认证的问题。另外作者还讨论了这些密码学问题之间的关联性以及如何相互转化。比如一个安全的密码系统(可以防御明文攻击)可以用来生成一个的单向函数、公钥加密系统可以用来作为单向认证、陷门密码系统可以用来生成一个公钥加密系统。数学难题的计算复杂度被当成一种保障密码学安全问题的有效工具被利用起来,这一重要思想贯穿现代密码学的许多加密算法。
3.密钥的产生过程
假设由A、B、C想协商产生一个共用的密钥,首先三方需要协商确定一个大的素数n和一个整数g(这两个数可以公开)
根据协商密钥的主体数量,可以确定需要协商的轮数,有N个主体,需要协商N-1轮。
3.1 第一轮信息交换
A选取一个大的随机整数x,并且发送$X\ =\ g^x\ mod\ n $给B
B选取一个大的随机整数y,并且发送$Y\ =\ g^y\ mod\ n $给C
C选取一个大的随机整数z,并且发送$Z\ =\ g^z\ mod\ n $给A
3.2 第二轮信息交换
A计算$X1\ =\ Z^x\ mod\ n $给B
B计算$Y1\ =\ X^y\ mod\ n $给C
C计算$Z1\ =\ Y^z\ mod\ n $给A
3.3 计算密钥
A计算$k1\ =\ Z1^x\ mod\ n$
B计算$k2\ =\ X1^y\ mod\ n$
C计算$k3\ =\ Y1^z\ mod\ n$
$Key\ =\ k1\ =\ k2\ =\ k3$,为共同协商出来的密钥,A、B、C将用协商好的密钥进行数据加密通信。
4.算法的实现
import random
def diffie_hellman():
n = 173
g = random.randint(1,10)
x = random.randint(1,10)
y = random.randint(1,10)
z = random.randint(1,10)
X = g**x % n
Y = g**y % n
Z = g**z % n
X1 = Z**x % n
Y1 = X**y % n
Z1 = Y**z % n
k1 = Z1**x % n
k2 = X1**y % n
k3 = Y1**z % n
print('n g x y z:',n,g,x,y,z)
print("A 要给 B 发送的数据 X:",X)
print("B 要给 C 发送的数据 Y:",Y)
print("C 要给 A 发送的数据 Z:",Z)
print("A 要给 B 发送的数据 X1:",X1)
print("B 要给 C 发送的数据 Y1:",Y1)
print("B 要给 C 发送的数据 Z1:",Z1)
print(k1,k2,k3)
diffie_hellman()
输出
n g x y z: 173 3 9 4 10
A 要给 B 发送的数据 X: 134
B 要给 C 发送的数据 Y: 81
C 要给 A 发送的数据 Z: 56
A 要给 B 发送的数据 X1: 92
B 要给 C 发送的数据 Y1: 85
B 要给 C 发送的数据 Z1: 138
169 169 169
A、B、C共同协商出来的密钥为8
D-H算法不足之处
Diffie-Hellman算法并不能防止假冒攻击,当主体存在篡改时,密钥将会被泄露,所以Diffie-Hellman算法不是一个完美的密钥协商算法,这个时候可以使用EKE协议进行密钥的协商。
评论 (0)