SSL/TLS协议简介
目录
1 概述
2 主要功能
3 技术演化
3.1 明文时代
3.2 对称加密时代
3.3 非对称加密时代
3.4 公证时代
2.5 SSL/TLS协议时代
4 组件协议
4.1 握手协议(Handshake Protocol)
4.2 加密协议(Record Protocol)
4.3 警报协议(Alert Protocol)
5 主要应用
6 Python示例
6.1 服务器端代码 (server.py)
6.2 客户端代码 (client.py)
6.3 生成自签名的证书
6.4 测试
1 概述
SSL(Secure Sockets Layer) 是一种网络安全协议,用于在互联网中保护数据的传输。SSL 协议最初由网景公司(Netscape)开发,旨在为通过互联网传输的数据提供加密保护。由于 SSL 协议存在一些安全问题,它在 1999 年被其继任者 TLS(Transport Layer Security) 取代。尽管 TLS 是 SSL 的继任者,但 SSL 和 TLS 常常被统称为 SSL/TLS,尤其在日常用语中。
直白点说,就是在明文的上层和TCP层之间加上一层加密,这样就保证上层信息传输的安全。如HTTP协议是明文传输,加上SSL层之后,就有了雅称HTTPS
。它存在的唯一目的就是保证上层通讯安全的一套机制。
2 主要功能
-
加密:SSL/TLS 使用加密算法确保数据在传输过程中不会被窃取或篡改。加密使得数据只能由授权的接收者解密和读取。
-
认证:SSL/TLS 通过证书验证通信双方的身份,确保数据的接收者和发送者都是合法的。
-
数据完整性:SSL/TLS 使用消息认证码(MAC)来检测数据在传输过程中是否被篡改,确保数据的完整性。
3 技术演化
熟悉一套技术的演化过程,比直接看最新版本,更容易理解。
3.1 明文时代
Bob向Alice发送信息,直接以明文形式发送。
缺点显而易见,第三方黑客很容易就窃取到信息,也可以进行篡改后发给Alice,而且Alice收到后并不知情,以为是Bob发来的。
3.2 对称加密时代
Bob和Alice保存一份相同的秘钥,Bob发出的信息先经过加密,Alice收到后使用同样的密码进行解密。这种加密和解密使用同一个密钥的算法称为对称加密算法。
短期内黑客对加密数据无能为力,但是每次变更秘钥需要事先协商,如果协商出问题,Bob告知Alice新秘钥时,秘钥被黑客截取,那后续的密文对黑客来说,他也可以解密成明文。也可以篡改明文信息后,再使用同样的密钥加密后发给Alice。
3.3 非对称加密时代
既然进行密钥交换存在风险,Bob和Alice采用非对称加密算法。双方各自保存私钥、公钥,两者配对,私钥自己保存,公钥由私钥运算生成发给对方,不能由公钥反推算出私钥;但是使用公钥加密的密文,却可以使用私钥解密;使用私钥签名,使用公钥验证;这种加密和解密使用不同的密钥的算法成为非对称加密算法。
通信前,双发先将自己的公钥发给对方,私钥保密;Bob先使用Alice提供的公钥加密数据,同时也使用自己的私钥进行签名标记,一起打包后发给Alice,Alice使用自己的私钥进行解密,再使用Bob的公钥进行验证,确认收到的信息是否来自Bob。
这种形式的加密通信,协商传输的是公钥,即使被黑客截取,他也不能解密后续的信息,因为解密得使用私钥。
但是百密一疏,如果黑客在最初交互公钥时,截取公钥,把Bob发给Alice的公钥截取,把自己的假公钥发给Alice;截取Alice发出的数据,黑客用自己的私钥解密,然后再使用自己的私钥加密后发给Bob。
整了这么复杂的一套加密协议,结果还是存在隐患。
3.4 公证时代
问题就出在公钥交换,Alice收到一份公钥,如何证明这公钥确实是Bob发出的?譬如买房,只有房管局确认盖章导入系统的房产证,才是真的房产证,才能放心进行交易。通过CA(Certificate Authority)证书颁发机构来保证公钥的真实性,为公钥的真实性进行担保公证。
CA也是基于非对称加密算法,Bob先先把自己的公钥交给CA,CA用自己的私钥加密这些数据,加密完的数据称为Bob的数字证书,先前Bob发给Alice的公钥,改为发送CA加密之后的数字证书。Alice收到以后,通过CA发布的CA证书(包含了CA的公钥),来解密Bob的数字证书,从而获得Bob的公钥。
问题是Alice怎么确保CA证书不是黑客伪造的?CA证书是提前预置在浏览器或操作系统,或者嵌入式设备内,不需要联网获取,自然也不存在劫持篡改的问题。
虽然黑客还是可以拦截带公钥的数字签名证书,可以用CA公钥解密看到内容;但是他没CA的秘钥,无法伪造出正确的数字签名证书,也就是Bob的真实公钥黑客可见不可改,改了Alice会发现异常,但只有公钥并没什么价值。
2.5 SSL/TLS协议时代
公证时代的解决方案就是SSL/TLS协议加密通信基础。
因为使用非对称加密算法比对称加密算法要复杂,消耗运算资源,为考虑效率,非对称加密只会用来传递一条信息,即对称加密的密钥。对称加密的密钥确定,后续有效信息使用对称加密算法进行网络传输。既保证了网络通信的安全性,又不影响效率。
SSL/TLS协议的基本过程:
1、通过CA体系交换公钥
2、使用非对称加密算法,交换用于对称加密的密钥
3、有效数据使用对称加密算法,进行密文传输
前两步又称为"握手阶段"(handshake),是SSL/TLS加密通信的基础。
4 组件协议
SSL/TLS 协议的架构主要包括以下几个组件:
4.1 握手协议(Handshake Protocol)
握手协议用于在客户端和服务器之间建立安全连接。握手协议的主要任务是协商加密算法、密钥和验证双方的身份。握手协议的过程包括以下步骤:
-
客户端Hello:客户端发送一个 "Hello" 消息到服务器,包含客户端支持的 SSL/TLS 版本、加密套件(cipher suites)、会话 ID 等信息。
-
服务器Hello:服务器回复一个 "Hello" 消息,选择一个加密套件并确认使用的 SSL/TLS 版本。服务器还会发送其证书,以便客户端进行身份验证。
-
证书交换:服务器将其数字证书(通常由受信任的证书颁发机构签发)发送给客户端。客户端使用证书中的公钥来验证服务器的身份。
-
密钥交换:客户端和服务器交换密钥信息以生成对称加密密钥。密钥交换可以通过多种方式进行,如 Diffie-Hellman 或 RSA。
-
完成握手:双方交换 "Finished" 消息,确认握手过程已成功完成。此时,双方开始使用协商好的加密算法和密钥进行加密通信。
4.2 加密协议(Record Protocol)
加密协议用于在 SSL/TLS 会话中加密和解密实际传输的数据。它负责将应用层数据分割成块,进行加密,并在接收端解密。加密协议包括以下步骤:
-
数据分块:将应用层数据分割成适当大小的数据块。
-
加密:使用对称密钥对数据块进行加密,确保数据在传输过程中的机密性。
-
数据传输:将加密的数据块发送到接收端。
-
解密:接收端使用相同的对称密钥解密数据块,恢复原始数据。
4.3 警报协议(Alert Protocol)
警报协议用于在 SSL/TLS 连接中报告错误或异常情况。警报协议的消息包括:
-
警报消息:包含错误的详细信息,如解密失败、证书过期等。
-
关闭通知:用于正常关闭连接,告知对方即将断开连接。
5 主要应用
在SSL/TLS出现之前,很多应用层协议(http、ftp、smtp等)都存在着网络安全问题。最常见的http协议,在传输过程中使用的是明文信息,传输报文一旦被截获便会泄露传输内容;传输过程中报文如果被篡改,对方无法轻易发现;无法保证消息交换的对端身份的可靠性。为了解决此类安全问题,在应用层和传输层之间加入了SSL/TLS协议,升级为https。SSL/TLS目前已经广泛用于数据安全协议。关于SSL/TLS有很多开源软件包,如OpenSSL,mbedtls等。OpenSSL功能更强大,mbedtls小巧更适合嵌入式设备。
6 Python示例
以下是一个简单的Python SSL/TLS服务器和客户端的示例代码。
6.1 服务器端代码 (server.py)
import socket
import ssl
# 服务器端的SSL/TLS证书和私钥
certfile = 'server.crt' # SSL/TLS证书文件
keyfile = 'server.key' # 私钥文件
# 创建TCP socket
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定地址和端口
tcp_server_socket.bind(('localhost', 10023))
tcp_server_socket.listen(5)
# 创建SSL/TLS socket
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain(certfile, keyfile)
ssl_server_socket = ssl_context.wrap_socket(tcp_server_socket, server_side=True)
print("Waiting for client connection...")
while True:
# 接受客户端连接
client_socket, addr = ssl_server_socket.accept()
print(f"Client connected: {addr}")
# 接收客户端消息
data = client_socket.recv(1024).decode()
print(f"Client sent: {data}")
# 发送响应到客户端
client_socket.sendall(b"Hello, Client!")
# 关闭客户端连接
client_socket.close()
6.2 客户端代码 (client.py)
import socket
import ssl
# 服务器IP和端口
server_address = ('localhost', 10023)
# 创建一个socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 创建SSL套接字上下文
context = ssl.create_default_context()
# 连接到服务器
with context.wrap_socket(sock, server_hostname=server_address[0]) as s:
s.connect(server_address)
# 发送消息到服务器
s.send(b'Hello from client!')
# 接收服务器响应
response = s.recv(1024)
print('Received:', response.decode())
6.3 生成自签名的证书
在运行这些示例之前,你需要生成SSL/TLS证书。可以使用OpenSSL来生成自签名的证书,例如:
openssl req -new -x509 -days 365 -nodes -out server.crt -keyout server.key
6.4 测试
然后,运行服务器端 (python server.py),随后运行客户端 (python client.py),你将看到客户端和服务器之间通过SSL/TLS安全地传输数据。