编程思路:
客户端和服务器端建立连接
客户端产生非对称密钥,将公钥传送给服务器端
服务器端通过公钥将密钥进行加密并传送给客户端
客户端接收到密钥并进行解密,双方开始通信
背景资料:
代码部分
注释已经非常详细了,这里就不再赘述。
异常类定义
class AuthenticationError ( Exception) :
def __init__ ( self, Errorinfo) :
super ( ) . __init__( )
self. errorinfo = Errorinfo
def __str__ ( self) :
return self. errorinfo
服务器端代码
服务器类定义:
import socket
import rsa
import pickle
from cryptography. fernet import Fernet
import hashlib
from errorclass import AuthenticationError
import time
from tlrobot import get_reply
class Server :
number = 0
def __init__ ( self, backlog= 5 , addr= ( 'localhost' , 8080 ) ) :
self. serverSocket = socket. socket( )
self. serverSocket. bind( addr)
self. serverSocket. listen( backlog)
def link_one_client ( self) :
clientSocket, addr = self. serverSocket. accept( )
Server. number = Server. number + 1
now_number = Server. number
print ( "和客户端{0}建立连接\n目标主机地址为:{1}" . format ( now_number, addr) )
publicKeyPK, pubKeySha256 = pickle. loads( clientSocket. recv( 1024 ) )
if hashlib. sha256( publicKeyPK) . hexdigest( ) != pubKeySha256:
raise AuthenticationError( "密钥被篡改!" )
else :
publicKey = pickle. loads( publicKeyPK)
print ( "已接受公钥" )
sym_key = Fernet. generate_key( )
en_sym_key = rsa. encrypt( pickle. dumps( sym_key) , publicKey)
en_sym_key_sha256 = hashlib. sha256( en_sym_key) . hexdigest( )
print ( "正在加密传送密钥" )
clientSocket. send( pickle. dumps( ( en_sym_key, en_sym_key_sha256) ) )
f = Fernet( sym_key)
while True :
time. sleep( 0.3 )
en_recvData = clientSocket. recv( 1024 )
recvData = f. decrypt( en_recvData) . decode( )
print ( "接受到客户端{0}传来的消息:{1}" . format ( now_number, recvData) )
sendData = get_reply( recvData)
en_sendData = f. encrypt( sendData. encode( ) )
clientSocket. send( en_sendData)
服务器端类实例化:
import threading
from serverclass import Server
print ( "欢迎使用服务端程序!" )
server = Server( )
while True :
t = threading. Thread( target= server. link_one_client)
t. start( )
客户端代码
客户端类定义:
import socket
import rsa
import pickle
from cryptography. fernet import Fernet
import hashlib
from errorclass import AuthenticationError
class Client :
def __init__ ( self) :
self. asyKey = rsa. newkeys( 2048 )
self. publicKey = self. asyKey[ 0 ]
self. privateKey = self. asyKey[ 1 ]
def link_server ( self, addr= ( 'localhost' , 8080 ) ) :
clientSocket = socket. socket( )
clientSocket. connect( addr)
print ( "正在向服务器传送公钥" )
sendKey = pickle. dumps( self. publicKey)
sendKeySha256 = hashlib. sha256( sendKey) . hexdigest( )
clientSocket. send( pickle. dumps( ( sendKey, sendKeySha256) ) )
symKey, symKeySha256 = pickle. loads( clientSocket. recv( 1024 ) )
if hashlib. sha256( symKey) . hexdigest( ) != symKeySha256:
raise AuthenticationError( "密钥被篡改!" )
else :
self. symKey = pickle. loads( rsa. decrypt( symKey, self. privateKey) )
print ( "密钥交换完成" )
f = Fernet( self. symKey)
while True :
sendData = input ( "输入你要发送的消息:" )
en_sendData = f. encrypt( sendData. encode( ) )
clientSocket. send( en_sendData)
en_recvData = clientSocket. recv( 1024 )
recvData = f. decrypt( en_recvData) . decode( )
print ( "接受到服务器传来的消息:{0}" . format ( recvData) )
客户端类实例化:
from clientclass import Client
print ( "欢迎使用客户端程序!" )
client = Client( )
client. link_server( )
调用图灵 机器人的代码
import requests
import json
def get_reply ( data) :
datas = {
'reqType' : 0 ,
"perception" : {
"inputText" : {
"text" : data
} ,
"selfInfo" : {
"location" : {
"city" : "武汉" ,
"province" : "湖北"
}
}
} ,
"userInfo" : {
"apiKey" : "*********************" ,
"userId" : "443545"
}
}
datas = json. dumps( datas)
url = "http://openapi.tuling123.com/openapi/api/v2"
r = requests. post( url= url, data= datas)
return json. loads( r. text) . get( "results" ) [ 0 ] . get( "values" ) . get( "text" )
参考资料:
cryptography
rsa
廖雪峰老师–网络编程
python(3.x) 实现AES 加解密
Socket通信原理