一、要实现基于自签名证书的客户端/服务器(C/S)网络安全应用程序,可以按照以下步骤:
-
生成自签名证书: 首先,需要生成一个自签名证书,用于服务器身份验证和加密通信。可以使用 OpenSSL 工具或其他证书管理工具生成自签名证书。自签名证书不是由公共颁发机构(CA)签名,因此通常只用于测试和开发验证目的(博文:使用OpenSSL生成自签名证书)。
-
服务器端实现: 在C/S模式中需要设计和合理分配所要实现的交互任务,本文采用博文:基于B/S的网络数据通信格式以及实例代码分析。为了加强安全认证,服务器端,需要编写代码来建立 SSL/TLS 连接,并使用自签名证书进行身份验证和加密。使用适当的编程语言和框架,例如 Python 的
ssl
模块或 Node.js 的https
模块,在服务器上创建 SSL 上下文对象,并加载自签名证书和私钥。然后,使用 SSL 上下文对象创建 SSL/TLS 服务器,并在指定的端口上监听连接请求。 -
客户端实现: 在客户端,需要编写代码来建立与服务器的 SSL/TLS 连接,并验证服务器的证书。使用适当的编程语言和框架,例如 Python 的
ssl
模块或 Node.js 的https
模块,在客户端上创建 SSL 上下文对象,并加载自签名证书(可选)。然后,使用 SSL 上下文对象创建 SSL/TLS 客户端,并连接到服务器的 IP 地址和端口。 -
通信和数据交换: 一旦 SSL/TLS 连接建立,服务器和客户端之间可以进行加密的通信。服务器和客户端可以通过 SSL/TLS 连接发送和接收数据,确保数据的机密性和完整性。在应用程序中,根据需求和协议,定义服务器和客户端之间的通信协议和消息格式。
二、实现
1, 环境要求: 环境中已经实现了客户端和服务器端对应
其中cprivate.key ,ccsr.csr,ccertificate.srt 分别是客户端的私钥,申请文件,签名文件;sprivate.key ,scsr.csr,scertificate.srt 分别是服务端的私钥,申请文件,签名文件
2, C/S业务功能实现
服务端s业务源码源码是
import socket
my_dict={}
my_dict["what is your name"]='i am tom'
my_dict["how old are you"]='22'
my_dict['hi']='hi'
for key in my_dict:
print(key)
for key,v in my_dict.items():
print(key)
print(v)
ser=socket.socket()
ser.bind(('127.0.0.1',8080))
ser.listen(1)
conn,add=ser.accept()
print(add)
while True:
data=conn.recv(1024)
data=data.decode()
print(data)
conn.sendall(my_dict.get(data,'no').encode())
conn.close()
ser.close()
客户端 c业务源码是
import codecs
import socket
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',8080))
while True:
c1=input(":")
print(c1)
c1=c1.encode()
print(c1)
client.sendall(c1)
data=client.recv(1024)
print(data.decode())
client.close()
# from ZMQ@cuc
通过抓包可见,使用明文方式的C/S交互没有任何安全机制,容易被嗅探。
现把基于 OpenSSL产生的自签名证书应用用于C/S交互,实现数据的解密和安全验证
3 基于 OpenSSL自签名的安全应用
服务端实现步骤:
1)创建一个上下文对象(上下文对象(Context Object)是用于配置和管理安全通信的参数和选项的数据结构)用于安全封装数据的包装盒:
import ssl
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
# ssl.PROTOCOL_TLS表示选择ssl模块中的TLS协议版本
- 在上下文中加载证书文件和密钥
context.load_cert_chain(certfile="scertificate.crt", keyfile="sprivate.key")
3)使用 SSL 上下文对象创建 TLS 服务器,并在指定的端口上监听连接请求。
ser=socket.socket()
ser.bind(('127.0.0.1',8080))
ser.listen(1)
ssl_s=context.wrap_socket(ser,server_side=True)
#创建服务器端的 SSL/TLS 套接
conn,add=ssl_s.accept()
#接收连接请求,后面的数据交互过程使用 SSL/TLS 的安全套接ssl_s
服务端完整代码
import socket
my_dict={}
my_dict["what is your name"]='i am tom'
my_dict["how old are you"]='22'
my_dict['hi']='hi'
import ssl
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.load_cert_chain(certfile="scertificate.crt", keyfile="sprivate.key")
for key in my_dict:
print(key)
for key,v in my_dict.items():
print(key)
print(v)
ser=socket.socket()
ser.bind(('127.0.0.1',8080))
ser.listen(1)
ssl_s=context.wrap_socket(ser,server_side=True)
conn,add=ssl_s.accept()
print(add)
while True:
data=conn.recv(1024)
data=data.decode()
print(data)
conn.sendall(my_dict.get(data,'no').encode())
conn.close() #一次会话
ssl_s.close()
客户端实现:
1)创建一个上下文对象(上下文对象(Context Object)是用于配置和管理安全通信的参数和选项的数据结构)用于安全封装数据的包装盒:
import ssl
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.load_verify_locations("scertificate.crt")
- 在上下文中加载证书文件和密钥
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
3)使用 SSL 上下文对象创建封装socket连接对象client,并连接到指定的端口
ssl_client=context.wrap_socket(client)
ssl_client.connect(('127.0.0.1',8080))
#在数据交互中将使用ssl_client进行数据的接收和回应
完整代码
import socket
import codecs
import ssl
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.load_verify_locations("scertificate.crt")
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ssl_client=context.wrap_socket(client)
ssl_client.connect(('127.0.0.1',8080))
while True:
c1=input(":")
print(c1)
c1=c1.encode()
print(c1)
ssl_client.sendall(c1)
data=ssl_client.recv(1024)
print(data.decode())
ssl_client.close()
四,对以上的交互过程进行抓包可见,已经在交互的数据上封装了安全头,无法直接嗅探到C S之间的交互数据内部信息