【计算机网络考研】P55: 其他应用层协议与网络安全入门
目录
博主智算菩萨,专注于人工智能、Python编程、音视频处理及UI窗体程序设计等方向。致力于以通俗易懂的方式拆解前沿技术,从零基础入门到高阶实战,陪伴开发者共同成长。目前已开设五大技术专栏,累计发布多篇原创技术文章,深受读者好评。
📌 专栏导航
- 人工智能前沿知识(已更191篇):深度剖析Transformer架构、生成式AI、强化学习、具身智能、神经符号系统、大模型及智能体(Agent)技术,系统性解析AI核心技术体系与前沿趋势。
- Python基础小白编程(已更232篇):从零开始,以保姆式教程讲解变量、数据类型、流程控制、函数等核心语法,配有大量实战代码与避坑指南,真正做到学以致用。
- 机器学习与深度学习(125篇):系统化拆解线性模型、决策树、随机森林、梯度提升树、神经网络等算法原理与工程实践,覆盖从公式推导到代码实现的全链路内容。
- 音频、图像与视频处理理论与实战(81篇):涵盖FFmpeg多媒体处理、audio_shop开源工具、ComfyUI-WanVideoWrapper视频生成等实用技术,从基础操作到高级应用一应俱全。
- UI窗体程序设计实战(78篇):深入讲解UI设计、动态窗体生成、游戏UI框架设计等实战技巧,提供从配置到编码的完整解决方案。
智算菩萨,以代码为经,以算法为纬,在人工智能的星辰大海中,做你前行路上最可靠的导航者。本人最常用AI工具为AIGCBAR。
1. DHCP 协议:应用层视角
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)在前面网络层的章节中已有详细讨论。本小节从应用层的视角补充 DHCP 的核心工作流程。
1.1 DHCP 四步握手
DHCP 使用 UDP 作为传输层协议,通过著名的四步握手过程为设备自动分配 IP 地址:
第一步:DHCP Discover(发现)
新接入网络的设备(DHCP 客户端)还没有 IP 地址,它会在本地网络中广播一个 DHCP Discover 报文(源 IP: 0.0.0.0,目的 IP: 255.255.255.255)。这个报文相当于客户端在大喊:“我是新来的,需要一个 IP 地址,有 DHCP 服务器吗?”
第二步:DHCP Offer(提供)
网络中的 DHCP 服务器收到 Discover 报文后,会从地址池中选择一个可用的 IP 地址,连同子网掩码、默认网关、DNS 服务器地址等配置信息,以广播方式发送 DHCP Offer 报文给客户端。
第三步:DHCP Request(请求)
客户端可能收到多个 DHCP 服务器的 Offer(如果网络中有多个 DHCP 服务器)。客户端会选择其中一个 Offer,然后广播发送 DHCP Request 报文,告知所有 DHCP 服务器它选择了哪个 Offer。
第四步:DHCP ACK(确认)
被选择的 DHCP 服务器收到 Request 后,发送 DHCP ACK 报文确认分配。其他 DHCP 服务器收到 Request 后,会回收它们之前 Offer 的 IP 地址。客户端收到 ACK 后,就可以使用分配的 IP 地址了。
与 P34 网络层视角的互补:从网络层角度看,DHCP 是主机获取网络层配置信息的机制;从应用层角度看,DHCP 是一个应用层协议,它使用 UDP(端口 67 服务器端,68 客户端),通过报文交互完成地址分配。这种"跨层"的视角有助于全面理解 DHCP 的设计。
1.2 DHCP 报文类型
| 报文类型 | 说明 |
|---|---|
| DISCOVER | 客户端广播寻找 DHCP 服务器 |
| OFFER | 服务器响应,提供 IP 地址 |
| REQUEST | 客户端请求使用某个服务器提供的 IP |
| ACK | 服务器确认分配 |
| NAK | 服务器拒绝分配(请求的地址无效或已分配) |
| RELEASE | 客户端释放 IP 地址 |
| INFORM | 客户端已有 IP,仅请求其他配置参数 |
2. SNMP:简单网络管理协议
**SNMP(Simple Network Management Protocol,简单网络管理协议)**是用于网络设备监控和管理的应用层协议。
2.1 SNMP 的基本架构
SNMP 采用管理者-代理(Manager-Agent)模型:
网络管理系统(NMS,Manager):运行在网络管理中心的软件,负责监控和管理网络中的各种设备。管理员通过 NMS 查看设备状态、接收告警、执行配置变更。
代理(Agent):运行在被管理设备(路由器、交换机、服务器、打印机等)上的软件。代理负责收集本地的管理信息,响应管理者的查询,并在特定条件下主动发送告警。
管理信息库(MIB,Management Information Base):
MIB 是一个层次化的数据库,定义了被管理设备上所有可监控和配置的参数。MIB 使用**对象标识符(OID)**来唯一标识每个管理对象,OID 采用树形层次结构(类似 DNS 的域名结构)。
例如:
1.3.6.1.2.1.1.1.0表示系统描述(sysDescr)1.3.6.1.2.1.1.3.0表示系统运行时间(sysUpTime)1.3.6.1.2.1.2.2.1.10.1表示接口接收的字节数
2.2 SNMP 的操作类型
| 操作 | 说明 | 方向 |
|---|---|---|
| Get | 管理者查询代理的一个或多个 OID 值 | Manager → Agent |
| GetNext | 查询指定 OID 的下一个 OID 值(用于遍历表) | Manager → Agent |
| GetBulk | 批量获取大量数据(SNMPv2+) | Manager → Agent |
| Set | 管理者设置代理的一个 OID 值(远程配置) | Manager → Agent |
| Trap | 代理主动向管理者发送告警通知 | Agent → Manager |
| Inform | 带确认的 Trap(SNMPv2+) | Agent → Manager |
2.3 SNMP 的版本
| 版本 | 特点 |
|---|---|
| SNMPv1 | 最早的版本,使用社区字符串(明文密码)进行认证,安全性差 |
| SNMPv2c | 改进了功能和性能,但仍使用社区字符串认证 |
| SNMPv3 | 增加了安全性:认证(MD5/SHA)、加密(DES/AES)和访问控制 |
2.4 Trap 陷阱通知
**Trap(陷阱)**是 SNMP 中一种重要的主动通知机制。当代理检测到特定事件发生时(如链路断开、CPU 过载、温度过高等),可以主动向管理者发送 Trap 通知,而不需要管理者不断轮询。
常见的 Trap 类型包括:
- coldStart:代理重新初始化,配置可能改变
- warmStart:代理重新初始化,配置未改变
- linkDown:网络接口断开
- linkUp:网络接口恢复
- authenticationFailure:认证失败
3. P2P 应用:BitTorrent 与 DHT
3.1 BitTorrent 协议
BitTorrent 是目前最流行的 P2P 文件共享协议。它的核心设计思想是将大文件分割成许多小块,由多个对等方同时交换这些块。
BitTorrent 的核心概念:
种子文件(.torrent):一个小的元数据文件,包含以下信息:
- Tracker 服务器的地址
- 文件名称、大小、分块大小
- 每个块的 SHA-1 哈希值(用于完整性校验)
- 文件的创建时间、创建者等信息
Tracker:一个中心服务器(或服务器集群),负责维护有哪些对等方正在下载/上传某个文件。对等方在加入下载时向 Tracker 注册,Tracker 返回一个对等方列表。Tracker 本身不存储文件内容。
对等方(Peer):参与文件下载和上传的用户。每个对等方既从其他对等方下载块,也向其他对等方上传块。
种子(Seeder):已经拥有完整文件的对等方,只上传不下载。
下载过程:
- 用户获取种子文件(.torrent)
- BitTorrent 客户端解析种子文件,获取 Tracker 地址和文件分块信息
- 客户端向 Tracker 注册,获取一组对等方的地址
- 客户端与这些对等方建立连接,开始交换文件块
- 客户端优先下载稀缺的块(拥有者少的块),以提高整个系统的可用性
- 客户端采用** tit-for-tat(以牙还牙)**策略:优先向给自己上传快的对等方上传数据
- 当客户端收集到所有块后,它就成为一个新的种子(Seeder)
3.2 DHT:分布式哈希表
**DHT(Distributed Hash Table,分布式哈希表)**是一种去中心化的分布式存储系统,它将键值对存储分散在所有参与节点上。
在 BitTorrent 中,DHT 替代了传统的 Tracker。使用 DHT 的 BitTorrent 称为**无 Tracker(Trackerless)**模式。DHT 让每个对等方都成为一个小型的"Tracker",共同维护对等方信息。
DHT 的核心思想:
- 每个参与节点有一个唯一的节点 ID
- 每个种子文件(更准确地说,是 info_hash)也有一个唯一的 ID
- 节点负责存储与其 ID "距离"最近的种子文件的对等方列表
- 查找时,通过迭代查询逐步接近目标 ID 所在的节点
最常用的 DHT 协议是 Kademlia,它使用 XOR 距离度量,具有高效的查找性能(O(log N) 跳)。
4. 网络安全基础
在开放的网络环境中,数据在传输过程中面临多种安全威胁:窃听(Eavesdropping)、篡改(Tampering)、伪造(Forgery)和抵赖(Repudiation)。网络安全技术就是为了应对这些威胁。
4.1 对称加密:一把钥匙开一把锁
对称加密(Symmetric Encryption)使用同一把密钥进行加密和解密。就像一把普通的锁,用同一把钥匙可以锁上也可以打开。
| 算法 | 密钥长度 | 特点 | 安全性 |
|---|---|---|---|
| DES | 56 位 | 最早的现代加密标准,已被破解 | 不安全,已淘汰 |
| 3DES | 112/168 位 | DES 的三重应用,速度较慢 | 中等,逐步淘汰 |
| AES | 128/192/256 位 | 当前主流标准,速度快、安全性高 | 高,推荐使用 |
对称加密的优点是速度快,适合加密大量数据。缺点是密钥分发困难——通信双方如何安全地共享密钥是一个难题(如果可以通过安全通道传密钥,那为什么不直接用这个通道传数据呢?)。
4.2 非对称加密:公钥与私钥
非对称加密(Asymmetric Encryption)使用一对密钥:公钥(Public Key)和私钥(Private Key)。公钥可以公开给任何人,私钥必须严格保密。
非对称加密的核心特性:
- 公钥加密,私钥解密:任何人可以用你的公钥加密消息,但只有持有私钥的你才能解密
- 私钥签名,公钥验证:你用私钥对消息签名,任何人都可以用你的公钥验证签名确实来自你
| 算法 | 特点 | 用途 |
|---|---|---|
| RSA | 最广泛使用的非对称算法,基于大整数分解的困难性 | 加密、数字签名、密钥交换 |
| ECC | 椭圆曲线加密,密钥更短,效率更高 | 移动设备、物联网设备 |
| DSA | 数字签名算法 | 仅用于数字签名 |
非对称加密解决了密钥分发问题,但速度比对称加密慢很多(通常慢 100-1000 倍),不适合加密大量数据。
实际应用中的混合加密:HTTPS 等协议使用混合加密方案——用非对称加密传输对称密钥,然后用对称加密传输实际数据。这样既解决了密钥分发问题,又保证了传输效率。
4.3 数字签名:身份认证 + 完整性
**数字签名(Digital Signature)**是实现身份认证和数据完整性的核心技术。
数字签名的过程:
- 发送方对消息计算哈希值(如 SHA-256)
- 发送方用私钥对哈希值进行加密,得到数字签名
- 发送方将原始消息 + 数字签名一起发送给接收方
- 接收方用公钥解密数字签名,得到哈希值 A
- 接收方对收到的消息计算哈希值 B
- 如果 A == B,说明消息确实来自发送方(私钥签名),且未被篡改(哈希一致)
数字签名同时实现了两个安全目标:
- 身份认证:只有持有私钥的人才能生成有效签名
- 完整性:消息的任何篡改都会导致哈希值不匹配
4.4 数字证书:公钥的身份证明
数字证书是由可信任的第三方机构(CA, Certificate Authority)颁发的电子文档,用于证明某个公钥确实属于某个实体(个人、组织或服务器)。
数字证书的内容:
| 字段 | 说明 |
|---|---|
| 版本号 | X.509 版本 |
| 序列号 | 证书的唯一标识 |
| 签名算法 | 签发证书使用的算法 |
| 颁发者 | CA 的名称 |
| 有效期 | 证书的起始和过期时间 |
| 主体 | 证书持有者的身份信息 |
| 主体公钥 | 证书持有者的公钥 |
| 扩展项 | 密钥用途、SAN(主体备用名称)等 |
| 签名 | CA 对证书内容的数字签名 |
证书链(Certificate Chain):
操作系统和浏览器内置了一批根 CA 证书(自签名的证书)。当验证一个服务器证书时,会沿着证书链向上验证:
服务器证书(由中间 CA 签发)→ 中间 CA 证书(由根 CA 签发)→ 根 CA 证书(内置信任)
如果整个链条的签名都验证通过,且证书未过期、未被吊销,就认为该服务器的身份可信。
5. HTTPS 协议:安全的 HTTP
**HTTPS(HyperText Transfer Protocol Secure)**是 HTTP 的安全版本,它在 HTTP 之下添加了 **SSL/TLS(Secure Sockets Layer / Transport Layer Security)**加密层。
5.1 HTTPS 的核心特性
- 加密:使用对称加密保护传输的数据,防止窃听
- 完整性:使用消息认证码(MAC)检测数据是否被篡改
- 身份认证:通过数字证书验证服务器的身份,防止中间人攻击
HTTPS 使用 TCP 端口 443(HTTP 使用端口 80)。
5.2 TLS 1.2 握手过程
TLS 握手是 HTTPS 建立安全连接的关键步骤。以下是 TLS 1.2 完整握手的过程:
第一步:Client Hello
客户端向服务器发送:
- 支持的 TLS 版本
- 支持的加密套件列表(Cipher Suites)
- 客户端随机数(Client Random,32 字节随机数)
- 支持的压缩方法
第二步:Server Hello
服务器回复:
- 选定的 TLS 版本
- 选定的加密套件
- 服务器随机数(Server Random,32 字节随机数)
- 服务器的数字证书(包含公钥)
第三步:客户端验证证书
客户端验证服务器的证书:
- 检查证书是否由可信的 CA 签发
- 检查证书是否过期
- 检查证书的域名是否与服务器的域名匹配
- 验证证书链
第四步:密钥交换
客户端生成预主密钥(Pre-Master Secret),用服务器的公钥加密后发送给服务器。服务器用私钥解密,获得预主密钥。
第五步:生成会话密钥
客户端和服务器使用以下材料生成对称会话密钥:
- Client Random
- Server Random
- Pre-Master Secret
双方独立计算,生成相同的会话密钥(用于对称加密)和 MAC 密钥(用于完整性校验)。
第六步:Finished
双方发送 Finished 消息,确认握手完成。之后所有通信都使用生成的会话密钥进行加密。
考研重点:TLS 握手使用非对称加密交换对称密钥(Pre-Master Secret),之后的通信使用对称加密(效率高)。
5.3 Mermaid 时序图:TLS 1.2 完整握手过程
图 7:TLS 1.2 完整握手时序图
5.4 TLS 握手与密钥交换的优化
TLS 1.2 的完整握手需要 2-RTT(Round-Trip Time),即两个完整的往返时间。TLS 1.3 对此进行了优化,将握手减少到 1-RTT(甚至 0-RTT 恢复会话)。
| 特性 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| 握手往返次数 | 2-RTT | 1-RTT(首次)/ 0-RTT(恢复) |
| 支持的加密算法 | 包括一些不安全的旧算法 | 仅保留安全的算法 |
| 握手消息 | 更多步骤 | 更简洁,将 ServerHello 和密钥交换合并 |
| 前向安全性 | 可选 | 强制要求(使用 ECDHE) |
| 性能 | 较慢 | 更快 |
6. 实战:Python 实现简易加密通信
下面我们用 Python 实现一个完整的加密通信工具,演示对称加密(AES/Fernet)和非对称加密(RSA)的工作原理。
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os
import base64
class SecureCommunication:
'''
加密通信工具 - 演示对称加密和非对称加密的完整流程
'''
def __init__(self):
self.symmetric_key = None
self.aesgcm = None
# ==================== 对称加密部分 ====================
def generate_symmetric_key(self):
'''
生成对称密钥(使用 Fernet,基于 AES-128-CBC)
Fernet 是一个高级对称加密 API,自动处理填充和认证
'''
self.symmetric_key = Fernet.generate_key()
return self.symmetric_key
def symmetric_encrypt(self, message):
'''
使用对称密钥加密消息
:param message: 要加密的字符串消息
:return: 加密后的 Base64 编码字符串
'''
if self.symmetric_key is None:
raise ValueError("请先调用 generate_symmetric_key() 生成密钥")
f = Fernet(self.symmetric_key)
# 将字符串编码为字节后加密
message_bytes = message.encode('utf-8')
encrypted = f.encrypt(message_bytes)
# 返回 Base64 编码的字符串
return encrypted.decode('ascii')
def symmetric_decrypt(self, token):
'''
使用对称密钥解密消息
:param token: 加密后的 Base64 编码字符串
:return: 解密后的原始字符串
'''
if self.symmetric_key is None:
raise ValueError("请先调用 generate_symmetric_key() 生成密钥")
f = Fernet(self.symmetric_key)
# 解密并解码为字符串
decrypted = f.decrypt(token.encode('ascii'))
return decrypted.decode('utf-8')
# ==================== AES-GCM 高级对称加密 ====================
def generate_aes_key(self, key_size=32):
'''
生成 AES-GCM 密钥
:param key_size: 密钥长度(16/24/32 字节,对应 AES-128/192/256)
:return: 生成的密钥
'''
self.aes_key = AESGCM.generate_key(bit_length=key_size * 8)
self.aesgcm = AESGCM(self.aes_key)
return self.aes_key
def aes_encrypt(self, plaintext):
'''
使用 AES-GCM 加密(提供认证加密,同时保证机密性和完整性)
:param plaintext: 要加密的字符串
:return: (nonce, ciphertext) 元组
'''
if self.aesgcm is None:
raise ValueError("请先调用 generate_aes_key() 生成密钥")
nonce = os.urandom(12) # GCM 推荐的 nonce 长度是 12 字节
plaintext_bytes = plaintext.encode('utf-8')
ciphertext = self.aesgcm.encrypt(nonce, plaintext_bytes, None)
# 返回 Base64 编码的 nonce 和密文
return base64.b64encode(nonce).decode('ascii'), base64.b64encode(ciphertext).decode('ascii')
def aes_decrypt(self, nonce_b64, ciphertext_b64):
'''
使用 AES-GCM 解密
:param nonce_b64: Base64 编码的 nonce
:param ciphertext_b64: Base64 编码的密文
:return: 解密后的字符串
'''
if self.aesgcm is None:
raise ValueError("请先调用 generate_aes_key() 生成密钥")
nonce = base64.b64decode(nonce_b64)
ciphertext = base64.b64decode(ciphertext_b64)
plaintext = self.aesgcm.decrypt(nonce, ciphertext, None)
return plaintext.decode('utf-8')
# ==================== 非对称加密部分 ====================
@staticmethod
def generate_rsa_keypair(key_size=2048):
'''
生成 RSA 密钥对
:param key_size: 密钥长度(推荐至少 2048 位)
:return: (私钥, 公钥) 元组
'''
private_key = rsa.generate_private_key(
public_exponent=65537, # 常用的公钥指数
key_size=key_size,
)
public_key = private_key.public_key()
return private_key, public_key
@staticmethod
def rsa_encrypt(public_key, message):
'''
使用 RSA 公钥加密
:param public_key: RSA 公钥对象
:param message: 要加密的字符串
:return: Base64 编码的密文
'''
message_bytes = message.encode('utf-8')
encrypted = public_key.encrypt(
message_bytes,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return base64.b64encode(encrypted).decode('ascii')
@staticmethod
def rsa_decrypt(private_key, encrypted_b64):
'''
使用 RSA 私钥解密
:param private_key: RSA 私钥对象
:param encrypted_b64: Base64 编码的密文
:return: 解密后的字符串
'''
encrypted = base64.b64decode(encrypted_b64)
decrypted = private_key.decrypt(
encrypted,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return decrypted.decode('utf-8')
@staticmethod
def rsa_sign(private_key, message):
'''
使用 RSA 私钥对消息进行数字签名
:param private_key: RSA 私钥对象
:param message: 要签名的字符串
:return: Base64 编码的签名
'''
message_bytes = message.encode('utf-8')
signature = private_key.sign(
message_bytes,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
return base64.b64encode(signature).decode('ascii')
@staticmethod
def rsa_verify(public_key, message, signature_b64):
'''
使用 RSA 公钥验证数字签名
:param public_key: RSA 公钥对象
:param message: 原始消息
:param signature_b64: Base64 编码的签名
:return: True(验证通过)或 False(验证失败)
'''
try:
message_bytes = message.encode('utf-8')
signature = base64.b64decode(signature_b64)
public_key.verify(
signature,
message_bytes,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
return True
except Exception:
return False
@staticmethod
def serialize_key(key, is_private=False):
'''
将密钥序列化为 PEM 格式字符串
:param key: 密钥对象
:param is_private: 是否为私钥
:return: PEM 格式的字符串
'''
if is_private:
return key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
).decode('ascii')
else:
return key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
).decode('ascii')
def main():
'''主程序:演示对称加密和非对称加密的完整流程'''
comm = SecureCommunication()
print("=" * 70)
print("加密通信工具演示")
print("=" * 70)
# ========== 1. 对称加密演示(Fernet / AES) ==========
print("\\n" + "=" * 70)
print("一、对称加密演示(Fernet - 基于 AES-128-CBC + HMAC)")
print("=" * 70)
# 生成密钥
key = comm.generate_symmetric_key()
print(f"\\n[1] 生成对称密钥:")
print(f" 密钥: {key.decode('ascii')}")
# 加密
original_message = "Hello, 这是一段需要加密的敏感信息!"
print(f"\\n[2] 原始消息:")
print(f" {original_message}")
encrypted = comm.symmetric_encrypt(original_message)
print(f"\\n[3] 加密后(Base64):")
print(f" {encrypted}")
# 解密
decrypted = comm.symmetric_decrypt(encrypted)
print(f"\\n[4] 解密后:")
print(f" {decrypted}")
print(f"\\n[5] 验证: 原始消息 == 解密消息: {original_message == decrypted}")
# ========== 2. AES-GCM 认证加密演示 ==========
print("\\n" + "=" * 70)
print("二、AES-GCM 认证加密演示(同时提供机密性和完整性)")
print("=" * 70)
aes_key = comm.generate_aes_key(key_size=32) # AES-256
print(f"\\n[1] 生成 AES-256-GCM 密钥:")
print(f" 密钥长度: {len(aes_key)} 字节 (256 位)")
secret_message = "这是一份绝密文件,使用 AES-GCM 加密保护!"
print(f"\\n[2] 原始消息: {secret_message}")
nonce, ciphertext = comm.aes_encrypt(secret_message)
print(f"\\n[3] 随机 Nonce: {nonce}")
print(f" 密文: {ciphertext[:60]}...")
decrypted_aes = comm.aes_decrypt(nonce, ciphertext)
print(f"\\n[4] AES-GCM 解密: {decrypted_aes}")
print(f" 验证通过: {secret_message == decrypted_aes}")
# ========== 3. 非对称加密演示(RSA) ==========
print("\\n" + "=" * 70)
print("三、非对称加密演示(RSA-2048)")
print("=" * 70)
# 生成 RSA 密钥对
private_key, public_key = SecureCommunication.generate_rsa_keypair(key_size=2048)
print(f"\\n[1] 生成 RSA-2048 密钥对:")
print(f" 私钥已生成(仅持有方知晓)")
print(f" 公钥已生成(可以公开给任何人)")
# 显示 PEM 格式的密钥
private_pem = SecureCommunication.serialize_key(private_key, is_private=True)
public_pem = SecureCommunication.serialize_key(public_key, is_private=False)
print(f"\\n 私钥(PEM 格式):")
print(f" {private_pem[:50]}...{private_pem[-25:]}")
print(f"\\n 公钥(PEM 格式):")
print(f" {public_pem[:50]}...{public_pem[-25:]}")
# 公钥加密
rsa_plaintext = "这是要用 RSA 公钥加密的机密消息"
print(f"\\n[2] 原始消息: {rsa_plaintext}")
rsa_encrypted = SecureCommunication.rsa_encrypt(public_key, rsa_plaintext)
print(f"\\n[3] 公钥加密后(Base64):")
print(f" {rsa_encrypted[:60]}...")
# 私钥解密
rsa_decrypted = SecureCommunication.rsa_decrypt(private_key, rsa_encrypted)
print(f"\\n[4] 私钥解密: {rsa_decrypted}")
# ========== 4. 数字签名演示 ==========
print("\\n" + "=" * 70)
print("四、数字签名演示(私钥签名 + 公钥验证)")
print("=" * 70)
important_message = "这是一份重要的合同文件,需要证明是我签署的。"
print(f"\\n[1] 待签名消息: {important_message}")
# 使用私钥签名
signature = SecureCommunication.rsa_sign(private_key, important_message)
print(f"\\n[2] 数字签名(Base64):")
print(f" {signature[:60]}...")
# 使用公钥验证签名
is_valid = SecureCommunication.rsa_verify(public_key, important_message, signature)
print(f"\\n[3] 公钥验证签名结果: {'✓ 验证通过(消息确实来自私钥持有者)' if is_valid else '✗ 验证失败'}")
# 篡改消息后的验证
tampered_message = important_message + "(已篡改)"
is_valid_tampered = SecureCommunication.rsa_verify(public_key, tampered_message, signature)
print(f"\\n[4] 篡改消息后验证: {'✓ 验证通过' if is_valid_tampered else '✗ 验证失败(检测到篡改!)'}")
# ========== 5. 混合加密(HTTPS 的核心思想) ==========
print("\\n" + "=" * 70)
print("五、混合加密演示(模拟 HTTPS 的核心机制)")
print("=" * 70)
print("\\n[场景] Alice 想安全地给 Bob 发送大量数据")
print(" 问题: 非对称加密太慢,对称加密的密钥如何安全传输?")
print(" 方案: 用 Bob 的公钥加密对称密钥,然后用对称加密传输数据")
# Alice 生成对称会话密钥
session_key = Fernet.generate_key()
print(f"\\n[1] Alice 生成会话密钥: {session_key.decode('ascii')[:20]}...")
# Alice 用 Bob 的公钥加密会话密钥
encrypted_session_key = SecureCommunication.rsa_encrypt(public_key, session_key.decode('ascii'))
print(f"[2] Alice 用 Bob 的公钥加密会话密钥")
print(f" 加密后的会话密钥: {encrypted_session_key[:50]}...")
# "网络传输" 加密后的会话密钥
print(f"\\n[3] === 网络传输(加密后的会话密钥)===")
# Bob 用私钥解密会话密钥
decrypted_session_key = SecureCommunication.rsa_decrypt(private_key, encrypted_session_key)
print(f"[4] Bob 用私钥解密会话密钥: {decrypted_session_key[:20]}...")
# Alice 用会话密钥加密实际数据
alice_comm = SecureCommunication()
alice_comm.symmetric_key = session_key
large_data = "这是一段很长的数据..." * 100 # 模拟大量数据
encrypted_data = alice_comm.symmetric_encrypt(large_data)
print(f"\\n[5] Alice 用会话密钥加密数据({len(large_data)} 字节 -> 对称加密)")
# Bob 用会话密钥解密数据
bob_comm = SecureCommunication()
bob_comm.symmetric_key = session_key
decrypted_data = bob_comm.symmetric_decrypt(encrypted_data)
print(f"[6] Bob 用会话密钥解密数据")
print(f" 解密成功: {large_data == decrypted_data}")
print("\\n" + "=" * 70)
print("总结:")
print(" - 对称加密(AES): 速度快,适合大量数据")
print(" - 非对称加密(RSA): 解决密钥分发问题")
print(" - 数字签名: 提供身份认证和完整性保护")
print(" - 混合加密: 结合两者优势(HTTPS 的核心原理)")
print("=" * 70)
if __name__ == '__main__':
main()
6.1 运行结果说明
运行上述代码,输出示例如下:
======================================================================
加密通信工具演示
======================================================================
======================================================================
一、对称加密演示(Fernet - 基于 AES-128-CBC + HMAC)
======================================================================
[1] 生成对称密钥:
密钥: gAAAAABl...
[2] 原始消息:
Hello, 这是一段需要加密的敏感信息!
[3] 加密后(Base64):
gAAAAABl...(一串 Base64 字符)
[4] 解密后:
Hello, 这是一段需要加密的敏感信息!
[5] 验证: 原始消息 == 解密消息: True
======================================================================
二、AES-GCM 认证加密演示(同时提供机密性和完整性)
======================================================================
[1] 生成 AES-256-GCM 密钥:
密钥长度: 32 字节 (256 位)
[2] 原始消息: 这是一份绝密文件,使用 AES-GCM 加密保护!
[3] 随机 Nonce: 3qYx9v...(12 字节的随机数)
密文: gAAAAABl...(加密后的数据)
[4] AES-GCM 解密: 这是一份绝密文件,使用 AES-GCM 加密保护!
验证通过: True
======================================================================
三、非对称加密演示(RSA-2048)
======================================================================
[1] 生成 RSA-2048 密钥对:
私钥已生成(仅持有方知晓)
公钥已生成(可以公开给任何人)
[2] 原始消息: 这是要用 RSA 公钥加密的机密消息
[3] 公钥加密后(Base64):
gAAAAABl...
[4] 私钥解密: 这是要用 RSA 公钥加密的机密消息
======================================================================
四、数字签名演示(私钥签名 + 公钥验证)
======================================================================
[1] 待签名消息: 这是一份重要的合同文件,需要证明是我签署的。
[2] 数字签名(Base64):
A1B2C3d...
[3] 公钥验证签名结果: ✓ 验证通过(消息确实来自私钥持有者)
[4] 篡改消息后验证: ✗ 验证失败(检测到篡改!)
======================================================================
五、混合加密演示(模拟 HTTPS 的核心机制)
======================================================================
[场景] Alice 想安全地给 Bob 发送大量数据
问题: 非对称加密太慢,对称加密的密钥如何安全传输?
方案: 用 Bob 的公钥加密对称密钥,然后用对称加密传输数据
[1] Alice 生成会话密钥: gAAAAABl...
[2] Alice 用 Bob 的公钥加密会话密钥
[3] === 网络传输(加密后的会话密钥)===
[4] Bob 用私钥解密会话密钥: gAAAAABl...
[5] Alice 用会话密钥加密数据(3300 字节 -> 对称加密)
[6] Bob 用会话密钥解密数据
解密成功: True
======================================================================
总结:
- 对称加密(AES): 速度快,适合大量数据
- 非对称加密(RSA): 解决密钥分发问题
- 数字签名: 提供身份认证和完整性保护
- 混合加密: 结合两者优势(HTTPS 的核心原理)
======================================================================
7. 应用层协议综合对比
在学习了本章所有应用层协议后,让我们做一个全面的总结对比:
| 协议 | 传输层 | 端口 | 核心功能 | 工作模式 |
|---|---|---|---|---|
| HTTP | TCP | 80 | Web 浏览 | C/S,请求-响应 |
| HTTPS | TCP | 443 | 安全 Web 浏览 | C/S,请求-响应 + TLS |
| FTP | TCP | 21/20 | 文件传输 | C/S,双连接 |
| DNS | UDP/TCP | 53 | 域名解析 | C/S,查询-响应 |
| SMTP | TCP | 25 | 发送邮件 | C/S,推送 |
| POP3 | TCP | 110/995 | 接收邮件(离线) | C/S,下载-删除 |
| IMAP | TCP | 143/993 | 接收邮件(在线) | C/S,同步 |
| DHCP | UDP | 67/68 | 自动分配 IP | C/S,四步握手 |
| SNMP | UDP | 161/162 | 网络管理 | Manager-Agent |
| BitTorrent | TCP/UDP | 随机 | P2P 文件共享 | P2P |
| TLS/SSL | TCP | - | 安全传输 | 握手协议 |
8. 考研易错点与经典例题
易错点一:DHCP 的 UDP 端口
易错提醒:DHCP 服务器使用 UDP 端口 67,客户端使用 UDP 端口 68。不要混淆!
易错点二:混淆加密算法的用途
易错提醒:
- 对称加密(AES):加密大量数据,速度快
- 非对称加密(RSA):交换对称密钥、数字签名
- 哈希函数(SHA-256):完整性校验、数字签名中生成消息摘要
- 数字证书:验证公钥的身份
易错点三:HTTPS 的层次
易错提醒:HTTPS 不是独立的协议,而是 HTTP + SSL/TLS。TLS 位于应用层(HTTP)和传输层(TCP)之间,常被称为"安全套接层"或"传输层安全"。从考研角度看,可以认为 HTTPS = HTTP 在 TLS 之上运行,TLS 在 TCP 之上运行。
经典例题
例题 1:在 HTTPS 中,TLS 握手的主要目的是什么?
A. 验证客户端身份
B. 协商对称加密的会话密钥
C. 压缩 HTTP 数据
D. 缓存 Web 页面
解析:答案是 B。TLS 握手的主要目的是协商生成对称加密的会话密钥。服务器身份的验证(通过数字证书)也是握手的一部分,但核心目标是安全地交换对称密钥。
例题 2:下列关于网络安全的描述中,正确的是?
A. 对称加密的密钥分发比非对称加密更安全
B. 非对称加密比对称加密更适合加密大量数据
C. 数字签名可以保证消息的机密性
D. 数字证书用于验证公钥的持有者身份
解析:答案是 D。A 错误,对称加密的密钥分发是难题;B 错误,非对称加密速度慢,不适合大量数据;C 错误,数字签名保证的是认证和完整性,不保证机密性(签名是公开的);D 正确,数字证书由可信的 CA 签发,证明公钥确实属于证书上标识的实体。
例题 3:在 SNMP 中,当代理检测到链路断开时,主动向管理者发送的通知称为?
A. Get B. Set C. Trap D. Response
解析:答案是 C。Trap 是 SNMP 中代理主动向管理者发送的告警通知,无需管理者轮询查询。Get 和 Set 是管理者发起的操作,Response 是对 Get/Set 的响应。
9. 总结与展望
至此,我们已经完成了计算机网络从物理层到应用层的全面学习。应用层作为最接近用户的一层,承载着互联网最丰富多样的服务——Web 浏览、电子邮件、文件传输、域名解析、网络管理等。
在考研复习中,应用层需要重点掌握:
- DNS:域名空间层次结构、四类 DNS 服务器、递归查询和迭代查询的区别、DNS 缓存机制
- HTTP:请求-响应模型、GET vs POST、状态码分类、Cookie/Session、版本演进(HTTP/1.1 vs HTTP/2)
- FTP:双连接设计(控制连接 + 数据连接)、主动模式 vs 被动模式
- 电子邮件:SMTP(发送)、POP3/IMAP(接收)、MIME(格式扩展)
- 网络安全:对称加密 vs 非对称加密、数字签名、数字证书、TLS 握手
应用层协议的共同特点是:它们都基于传输层提供的端到端通信服务,通过定义应用特定的报文格式和交换规则,实现了丰富多彩的网络应用。理解这些协议的设计思想和工作原理,不仅有助于应对考试,更是深入理解互联网运作机制的关键。
版权声明:本系列教程仅供学习交流使用,未经许可不得用于商业用途。
编写说明:本教程基于 408 考研计算机网络大纲编写,内容覆盖考研全部知识点,同时配合 Python 实战代码帮助加深理解。所有代码均经过测试,确保可运行。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)