目前常用的加密算法主要有:哈希算法(比如MD5、SHA族、Hmac),对称加密算法(比如AES),非对称加密算法(RSA),以及Diffie-Hellman密钥协商算法等等,这几种算法都有各自的特点,适合的场景也不一样,这里只做简单的介绍,想详细了解的话,网上资料很多,可以自行查看相关的资料。
各类算法的特点:
哈希算法:正向快速,不可逆性,即加密后是很难解密出明文的。经常用于数据加密和数据校验。
对称加密算法:AES是一种常用的对称加密算法,其特点是加解密都用同一个密钥。
非对称加密算法RSA:RSA算法是一种非对称加密算法,由一个私钥和一个公钥构成的密钥对,通过私钥加密,公钥解密,或者通过公钥加密,私钥解密。其中,公钥可以公开,私钥必须保密。
Diffie-Hellman密钥协商算法:Diffie-Hellman是一种密钥协商算法(简称DH算法),DH算法基于一种数学原理,能够在双方不泄露密钥的情况下协商出一种密钥来。
在客户端向服务器端发送数据的过程中,如果是比较重要的数据(比如密码,敏感数据等),一般需要先在客户端进行加密后再发送,服务器接收到数据后再进行解密得到原始数据。(反过来服务器返回数据给客户端也是一样的道理)
这里假设客户端和服务器端采用AES(对称加密算法)进行加解密传输的数据,AES加密算法有一个特点就是加解密都用同一个密钥(这里把该密钥称作secretKey),所以双方都通过secretKey进行数据加解密。
因此在客户端向服务器第一次传输数据的时候,客户端需要先向服务器端获取secretKey,并且保存在客户端,而这种直接向服务器获取明文secretKey的过程是很容易被第三者拦截的,也就是说这一过程是不安全的。(哈哈,除非是服务器把secretKey写到纸上,亲手偷偷地递给客户端)
因此呢,客户端向服务器获取secretKey的这一过程,也是需要进行加密的。
那么,服务器需要怎么做才能把secretKey安全的送达客户端呢?
目前常采用的方法有:RSA 或 Diffie-Hellman
严格来说,DH算法其实并不是一种加密算法,因为它本身并不是用于加密的,我的理解是用于双方协商计算,即双方按照某种合约进行计算,从而计算出一种相同的结果。
原理如下:
第一步:初始化
比如现在服务器提供了两个随机公钥数字(允许公开):pubN=10,modN=3;
客户端自己生成了一个随机私钥数字(不可公开,服务器也不知道):cPrivN=2;
服务器端也自己生成了一个随机私钥数字(不可公开,客户端也不知道):sPrivN=4;
第二步:客户端、服务器端分别基于相同的数学公式进行计算,计算结果称作公钥结果:pubResult
客户端进行数学计算:cPubResult = pubN * cPrivN % modN = 10 * 2 % 3 = 2;(计算结果允许公开)
服务器进行数学计算:sPubResult = pubN * sPrivN % modN = 10 * 4 % 3 = 1;(计算结果允许公开)
客户端和服务器端交换公钥结果,客户端得到sPubResult=1,服务器端得到cPubResult=2。
第三步:协商出一致的密钥数字:keyN(客户端和服务器端得出的结果是一致的)
客户端:cKeyN = sPubResult * cPrivN % modN= 1 * 2 % 3 = 2;
服务器:sKeyN = cPubResult * sPrivN % modN= 2 * 4 % 3 = 2;
到目前为止呢,双方都协商出了密钥,并且是一致的,但是呢,有没有见过密钥是number类型的?想必都没有吧,所以需要进行第四步,生成更长的密钥。
第四步:对密钥数字进行hash生成密钥串
const hash = crypto.createHash('sha256');
hash.update(this.keyN.toString());
this.secretKey = hash.digest('hex');
各类加密算法介绍目前常用的加密算法主要有:哈希算法(比如MD5、SHA族、Hmac),对称加密算法(比如AES),非对称加密算法(RSA),以及Diffie-Hellman密钥协商算法等等,这几种算法都有各自的特点,适合的场景也不一样,这里只做简单的介绍,想详细了解的话,网上资料很多,可以自行查看相关的资料。各类算法的特点:哈希算法:正向快速,不可逆性,即加密后是很难解密出明文的。经常用于数...
公
钥密码--
Diffie-Hellman密钥协商算法算法过程正确性安全性
博主是初学公
钥密码,本意是想整理一些经典的
密码系统,加深记忆也方便日后查找;整理成一个系列公
钥密码,方便检索。
如果有错,欢迎指正。
Diffie-Hellman密钥协商算法是由Whitfield Diffie,Martin E.Hellman在1976年发表的“New Directions in Cryptography”一文中提出。
Diffie-Hellman算法的思想是通过交换信息,来
协商出只有双方知道的
密钥。
算法过程
1、Diffie-Hellman算法简介
Diffie-Hellman算法(以下简称为:DH算法),是最早的密钥交换算法之一,它使得通信的双方能在非安全的信道中安全的交换密钥,用于加密后续的通信消息。
起基本流程原理如下:
假定小明和小红期望在一个不安全的网络中协商一个共同的密钥,那么进行如下步骤:
两人先说好大素数(质数)p和它的原始根g。
小明随机产生一个数a,并计算A = p^a mod g, 发送给小红。
小红随机产生一个数b,并计算......
两人首先
协商确定使用有限域Zp,即确定p为多少。本例为p=2579,域中本原元是α=2;
假如现在Alice要发送信息x=1299给Bob:
1、首先Bob选择随机数a=765做为自己的私
钥,通过私
钥计算β=2765mod 2579=949,Bob公开他的公
钥949给Alice。
2、Alice选择随机数K=853做为自己的私
钥
一、Diffie-Hellman算法简介
Diffie-Hellman算法是第一个公开密钥算法,早在 1976 年就发现了。其安全性源于在有限域上计算离散对数,比计算指数更为困难。该算法可以使两个用户之间安全地交换一个密钥,但不能用于加密或解密信息。
二、Diffie-Hellman密钥交换
Diffie-Hellman密钥交换方案(DHKE)提供了实际中密钥分配问题的解决方案,即它允许双方通过不...
def generate_prime_and_primitive_root():
while True:
p = random.randint(100, 1000) # 生成随机数p
if is_prime(p):
break
for i in range(2, p):
if math.gcd(i, p-1) == 1:
g = i
return p, g
# 判断是否为质数
def is_prime(num):
if num == 2 or num == 3:
return True
if num % 2 == 0 or num < 2:
return False
for i in range(3, int(num ** 0.5) + 1, 2):
if num % i == 0:
return False
return True
# Diffie-Hellman密钥交换
def diffie_hellman(sock):
# 生成大质数p和原根g
p, g = generate_prime_and_primitive_root()
# 发送p和g给对方
sock.sendall(str(p).encode())
sock.sendall(str(g).encode())
# 生成私钥a并计算公钥A
a = random.randint(2, p-2)
A = pow(g, a, p)
# 接收对方的公钥B
B = int(sock.recv(1024).decode())
# 计算共享密钥
K = pow(B, a, p)
# 发送公钥A给对方
sock.sendall(str(A).encode())
return K
# 主函数
def main():
# 创建套接字并连接服务器
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '127.0.0.1' # 服务器IP地址
port = 8000 # 服务器端口号
sock.connect((host, port))
# Diffie-Hellman密钥交换
K = diffie_hellman(sock)
# 输出共享密钥
print('共享密钥K为:', K)
# 关闭套接字
sock.close()
if __name__ == '__main__':
main()
在上面的代码中,我们首先使用`generate_prime_and_primitive_root()`函数生成了大质数p和原根g,并将它们发送给对方。然后,我们生成私钥a并计算公钥A,接收对方的公钥B,计算共享密钥K,最后将公钥A发送给对方。在`main()`函数中,我们创建套接字并连接服务器,执行Diffie-Hellman密钥交换,输出共享密钥K,最后关闭套接字。