python 实现socket加密通信(基于国密SM2、SM4)

python socket实现加密通信

  • 客户端代码:
  • 服务端代码:

使用网上的socket通信代码做了魔改
使用了gmssl库中的sm2、sm4算法实现通信

客户端代码:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
import socket
import time
from gmssl import sm2, func
from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
import hashlib

def create_key(data):#生成对称加密密钥,长度16的字符串
    m= hashlib.md5()
    m.update(data.encode("utf-8"))
    n=m.hexdigest()
    return n[0:16]

MaxBytes=1024*1024
host ='127.0.0.1'
port = 11223
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.settimeout(30)
client.connect((host,port))

public_key=client.recv(MaxBytes).decode()#连接后接收服务器的公钥
private_key = ''
sm2_crypt = sm2.CryptSM2(
    public_key=public_key, private_key=private_key)
    
while True:
    inputData=input();          #等待输入数据
    if(inputData=="quit"):
        print("我要退出了,再见")
        break
    if(inputData==''):
        print("请输入信息")
        continue

    ###发送数据
    key=create_key(inputData).encode()#生成对称密钥
    iv = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    crypt_sm4 = CryptSM4()
    crypt_sm4.set_key(key, SM4_ENCRYPT)
    encrypt_data = crypt_sm4.crypt_ecb(inputData.encode())  # 加密信息
    enc_key = sm2_crypt.encrypt(key)#对密钥进行加密
    sendBytes = client.send(encrypt_data)#客户端发送数据
    sendBytes2= client.send(enc_key)
    ###
    #print("客户端发送了:"+inputData)
    if sendBytes<=0:
        break;
    recvData = client.recv(MaxBytes)
    if not recvData:
        print('服务器不响应,退出')
        break
    localTime = time.asctime( time.localtime(time.time()))
    print(localTime,'服务器成功接受消息')
    #print(localTime, ' 接收到数据字节数:',len(recvData))
    
    #print(recvData.decode())
client.close()
print("关闭链接")

服务端代码:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
import socket
import time
from gmssl import sm2, func
from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
MaxBytes=1024*1024
private_key = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5'
public_key = 'B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207'

sm2_crypt = sm2.CryptSM2(
    public_key=public_key, private_key=private_key)
    
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.settimeout(60)
host = '127.0.0.1'
#host = socket.gethostname()
port = 11223
server.bind((host, port))        # 绑定端口
server.listen(1)                      # 监听
try:
    client,addr = server.accept()          # 等待客户端连接
    print(addr," 客户端连接")
    client.send(public_key.encode())#向客户端发送公钥
    while True:
        data = client.recv(MaxBytes)#服务器接受数据
        enc_key = client.recv(MaxBytes)#接受加密的密钥
        if not data:
            print('数据为空,链接中断')
            break
        localTime = time.asctime( time.localtime(time.time()))
        print(localTime,' 接收到数据字节数:',len(data))
        ###数据解密

        dec_key =sm2_crypt.decrypt(enc_key)#解出密钥
        print("得到密钥:"+dec_key.decode())
        iv = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'  # bytes类型
        crypt_sm4 = CryptSM4()
        crypt_sm4.set_key(dec_key, SM4_DECRYPT)
        dec_data = crypt_sm4.crypt_ecb(data)  #解出数据
        print("解密数据成功")
        print(dec_data.decode())

        ###
        client.send(("服务器收到"+dec_data.decode()).encode())

except BaseException as e:
    print("出现异常:")
    print(repr(e))
finally:
    server.close()                    # 关闭连接
    print("关闭链接")

你可能感兴趣的:(python,python,服务器,开发语言,安全,websocket)