Python基于socket实现安全Diffie-Hellman密钥交换协议

2022/6/18 5:20:05

本文主要是介绍Python基于socket实现安全Diffie-Hellman密钥交换协议,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

实验名称:基于socket实现安全Diffie-Hellman密钥交换协议

实验要求: 

  (1)掌握Diffie-Hellman密钥交换的原理;

  (2)了解socket通信的概念,掌握socket通信的编程方法;

  (3)能够编写基于客户/服务器端程序,运行程序并进行数据传输;

  (4)综合运用密码学机制设计和实现安全Diffie-Hellman密钥交换协议。

 

Socket:

  Socket接口规范可以适用多种通讯协议,主要是TCP/IP。TCP/IP的核心部分由操作系统的内核实现,应用程序通过编程接口来访问TCP/IP,应用程序通讯的方式如下图所示。

 

Diffie-Hellman密钥交换协议:

  假设p是大素数,g是p的本原根,p和g作为公开元素,协议如下:

  1. 用户Alice选择随机数XA,计算YA=gXA mod p,保密XA,发送YA给Bob ;
  2. 用户Bob选择随机数XB,计算YB=gXB mod p,保密XB,发送YB给Alice;
  3. Bob和Alice各自计算 k=YBXA mod p和k=YAXB mod p,从而得到共享密钥k。

  这是因为k=YBXA mod p=(gXB)XA mod p=(gXA)XB mod p=YAXB mod p。

 

代码实现:

实验语言:Python

实验环境:Pycharm 2021

 客户端代码:

import socket
import math
import random

def get_calculation(p, a, X):
    #得到计算数
   Y = (a ** X) % p
   return Y

def get_generator(p):
    #得到原根
   a = 2
   list = []
   while a < p:
      flag = 1
      while flag != p:
         if (a ** flag) % p == 1:
            break
         flag += 1
      if flag == (p - 1):
         list.append(a)
      a += 1
   return list

#得到交换计算数后的密钥
def get_key(X, Y, p):
   key = (Y ** X) % p
   return key
def Client(x):
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    host = "127.0.0.1"
    port = 8088
    # 连接服务端
    client.connect((host, port))
    send_msg = x
    # 发送数据,编码
    client.send(str(send_msg).encode("utf-8"))
    # 接收服务端返回的数据
    msg = client.recv(1024)
    # 解码
    print("接收到来自服务端的数据:%s" % msg.decode("utf-8"))
    # 关闭客户端
    client.close()
    return msg

if __name__ == "__main__":
    print("这里是客户端!")
    print("-"*20)
    p = 23 #双方公共数据为23
    # 得到素数的一个原根
    list = get_generator(p)
    # 得到A的私钥
    XA = random.randint(0, p - 1)
    # 得待A的计算数
    YA = get_calculation(p, int(list[-1]), XA)
    #交换计算数
    YB = int(Client(YA))
    # 交换后A的密钥
    key_A = get_key(XA, YB, p)
    print('客户端的生成密钥为:%d' % key_A)
    print("正在发送密钥至服务端比对...")
    judge_op = int(Client(key_A))
    if judge_op == key_A:
        print("比对成功,密钥相同!")

 服务端代码:

import socket
import math
import random

def get_calculation(p, a, X):
   Y = (a ** X) % p
   return Y

def get_generator(p):
    #得到原根
   a = 2
   list = []
   while a < p:
      flag = 1
      while flag != p:
         if (a ** flag) % p == 1:
            break
         flag += 1
      if flag == (p - 1):
         list.append(a)
      a += 1
   return list

#得到交换计算数后的密钥
def get_key(X, Y, p):
   key = (Y ** X) % p
   return key
def Server(x):
    # 创建一个socket对象
    socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    host = "127.0.0.1"
    port = 8088
    # 绑定地址
    socket_server.bind((host, port))
    # 设置监听
    socket_server.listen(5)
    client_socket, address = socket_server.accept()
    # 接收客户端的请求
    recvmsg = client_socket.recv(1024)
    # 把接收到的数据进行解码
    strData = recvmsg.decode("utf-8")
    print("接收到来自客户端的数据: %s" % strData)
    # 输入
    msg = x
    # 发送数据,需要进行编码
    client_socket.send(str(msg).encode("utf-8"))
    # 关闭服务器端
    socket_server.close()
    return recvmsg

if __name__ == "__main__":
    print("这里是服务端!")
    print("-"*20)
    p = 23
    list = get_generator(p)
    #得到B的私钥
    XB = random.randint(0, p-1)
    # 得到B的计算数
    YB = get_calculation(p, int(list[-1]), XB)
    #交换计算数
    YA = int(Server(YB))
    #交换后B的密钥
    key_B = get_key(XB, YA, p)
    print('服务端的生成密钥为:%d' % key_B)
    print("正在发送密钥至客户端比对...")
    judge_op = int(Server(key_B))
    if judge_op == key_B:
        print("比对成功,密钥相同!")

 

 实验总结:

  因为时间紧迫未实现界面化设计,且实验中所使用的p使用的固定数字,故可以将固定的p改进为可输入的大素数,将其传递给服务端,服务端确定后继续进行余下操作。



这篇关于Python基于socket实现安全Diffie-Hellman密钥交换协议的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程