2025-11-20 · 安全
32
安全 · 2025-11-20

密钥体系与加密通信 - 第1章:密码学基础

第1章:密码学基础(从零开始)

🎯 本章目标

学完这一章,你将理解:
- 对称加密和非对称加密的区别
- 哈希函数的作用
- 数字签名的原理
- 它们之间的关系和使用场景

预计学习时间: 30分钟


1.1 加密的本质:保护秘密

最简单的例子

小明给小红写情书:
原文:我喜欢你
加密:我喜欢你 → 3 6 9(每个字的拼音首字母位置)
小红收到:3 6 9
解密:3 6 9 → 我喜欢你

加密的核心: 让别人看不懂,但自己人能看懂。


1.2 对称加密:一把钥匙开一把锁

定义(初中生版)

对称加密 = 加密和解密用同一把钥匙

生活类比

你的家门锁:
- 用钥匙锁门(加密)
- 用同一把钥匙开门(解密)
- 如果钥匙丢了,别人也能开门 ❌

工作原理

发送方:
原文:Hello → [用密钥K加密] → 密文:X7@9#

传输:
密文:X7@9# → 网络传输 → 密文:X7@9#

接收方:
密文:X7@9# → [用同一个密钥K解密] → 原文:Hello

常见的对称加密算法

算法
密钥长度
速度
安全性
使用场景

AES
128/192/256位
很快
很高
最常用,推荐

DES
56位

低(已淘汰)
不推荐

3DES
168位
较慢
中等
逐渐淘汰

推荐使用:AES-256

代码示例:AES加密

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad

# 1. 生成密钥(256位 = 32字节)
key = get_random_bytes(32)

# 2. 创建加密器
cipher = AES.new(key, AES.MODE_CBC)

# 3. 加密数据
plaintext = b"Hello, World!"
ciphertext = cipher.encrypt(pad(plaintext, AES.block_size))

print(f"原文: {plaintext}")
print(f"密文: {ciphertext.hex()}")

# 4. 解密数据
decipher = AES.new(key, AES.MODE_CBC, cipher.iv)
decrypted = unpad(decipher.decrypt(ciphertext), AES.block_size)

print(f"解密: {decrypted}")

对称加密的优缺点

优点:
- ✅ 速度快(适合加密大量数据)
- ✅ 算法简单
- ✅ 资源消耗少

缺点:
- ❌ 密钥分发困难(如何安全地把密钥给对方?)
- ❌ 密钥管理复杂(100个人通信需要4950个密钥)
- ❌ 无法防抵赖(双方都有密钥,无法证明是谁加密的)


1.3 非对称加密:公钥加密,私钥解密

定义(初中生版)

非对称加密 = 加密和解密用不同的钥匙
- 公钥:可以公开,任何人都能用来加密
- 私钥:必须保密,只有自己能用来解密

生活类比

邮箱系统:
- 邮箱地址(公钥):任何人都知道,可以给你发邮件
- 邮箱密码(私钥):只有你知道,只有你能看邮件

别人用你的邮箱地址(公钥)发邮件(加密)
只有你用密码(私钥)才能看邮件(解密)

工作原理

密钥生成:
生成一对密钥 → 公钥(Public Key) + 私钥(Private Key)

加密过程:
发送方:原文 → [用接收方的公钥加密] → 密文
接收方:密文 → [用自己的私钥解密] → 原文

关键特点:
- 公钥加密的内容,只能用对应的私钥解密
- 私钥加密的内容,只能用对应的公钥解密

常见的非对称加密算法

算法
密钥长度
速度
安全性
使用场景

RSA
2048/4096位


最常用

ECC
256位
较快
很高
移动设备

DSA
1024/2048位
中等
中等
数字签名

推荐使用:RSA-2048 或 ECC-256

代码示例:RSA加密

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

# 1. 生成密钥对
key = RSA.generate(2048)
private_key = key
public_key = key.publickey()

# 2. 加密(用公钥)
cipher = PKCS1_OAEP.new(public_key)
plaintext = b"Hello, World!"
ciphertext = cipher.encrypt(plaintext)

print(f"原文: {plaintext}")
print(f"密文: {ciphertext.hex()}")

# 3. 解密(用私钥)
decipher = PKCS1_OAEP.new(private_key)
decrypted = decipher.decrypt(ciphertext)

print(f"解密: {decrypted}")

非对称加密的优缺点

优点:
- ✅ 密钥分发简单(公钥可以公开)
- ✅ 密钥管理简单(100个人只需要100对密钥)
- ✅ 可以防抵赖(私钥签名,公钥验证)

缺点:
- ❌ 速度慢(比对称加密慢100-1000倍)
- ❌ 只能加密小数据(RSA-2048最多加密245字节)
- ❌ 资源消耗大


1.4 对称 vs 非对称:如何选择?

对比表

维度
对称加密
非对称加密

密钥
1个(共享)
2个(公钥+私钥)

速度
很快
很慢

适用数据
大量数据
小量数据

密钥分发
困难
简单

典型算法
AES
RSA

使用场景
数据加密
密钥交换、数字签名

实际应用:混合加密

问题: 对称加密快但密钥分发难,非对称加密安全但速度慢。怎么办?

解决方案:混合使用!

HTTPS的加密流程:

1. 用非对称加密交换对称密钥
   客户端 → [用服务器公钥加密] → 对称密钥K → 服务器
   服务器 → [用自己私钥解密] → 得到对称密钥K

2. 用对称加密传输数据
   客户端 ←→ [用对称密钥K加密] ←→ 服务器

结果:
- 密钥分发安全(非对称加密)
- 数据传输快速(对称加密)

1.5 哈希函数:数据的"指纹"

定义(初中生版)

哈希函数 = 把任意长度的数据,变成固定长度的"指纹"

生活类比

身份证号:
- 每个人都有唯一的身份证号
- 看到身份证号就知道是谁
- 但不能从身份证号反推出这个人的样子

哈希值:
- 每个数据都有唯一的哈希值
- 看到哈希值就知道数据是否被修改
- 但不能从哈希值反推出原始数据

工作原理

输入:任意长度的数据
  ↓
哈希函数(如SHA256)
  ↓
输出:固定长度的哈希值(256位)

特点:
1. 单向性:不可逆(无法从哈希值推出原文)
2. 唯一性:不同数据的哈希值几乎不可能相同
3. 雪崩效应:数据改一个字节,哈希值完全不同

常见的哈希算法

算法
输出长度
速度
安全性
使用场景

SHA256
256位

很高
推荐使用

SHA512
512位
较快
很高
高安全场景

MD5
128位
很快
低(已破解)
不推荐

SHA1
160位

低(已破解)
不推荐

推荐使用:SHA256

代码示例:SHA256哈希

import hashlib

# 1. 计算哈希值
data = b"Hello, World!"
hash_value = hashlib.sha256(data).hexdigest()

print(f"原文: {data}")
print(f"SHA256: {hash_value}")

# 2. 验证数据完整性
data2 = b"Hello, World!"
hash_value2 = hashlib.sha256(data2).hexdigest()

if hash_value == hash_value2:
    print("✅ 数据未被修改")
else:
    print("❌ 数据已被篡改")

# 3. 雪崩效应演示
data3 = b"Hello, World?"  # 只改了一个字符
hash_value3 = hashlib.sha256(data3).hexdigest()

print(f"\n原文: {data}")
print(f"SHA256: {hash_value}")
print(f"\n改后: {data3}")
print(f"SHA256: {hash_value3}")
print("→ 完全不同!")

哈希函数的应用场景

1. 数据完整性校验

下载文件时:
文件 → 计算SHA256 → 对比官方提供的SHA256
  ├── 相同 → 文件完整 ✅
  └── 不同 → 文件被篡改 ❌

2. 密码存储

用户注册:
密码 → SHA256 → 存储哈希值(不存储明文密码)

用户登录:
输入密码 → SHA256 → 对比存储的哈希值

3. 数字签名

签名大文件:
文件 → SHA256 → 哈希值 → 用私钥签名
(不直接签名文件,而是签名哈希值,速度快)

1.6 数字签名:证明"我是我"

定义(初中生版)

数字签名 = 用私钥"签名",用公钥"验证"

生活类比

手写签名:
- 你用自己的笔迹签名(私钥签名)
- 别人对比你的签名样本验证(公钥验证)
- 每个人的签名都不同,无法伪造

数字签名:
- 你用私钥对数据签名
- 别人用你的公钥验证签名
- 私钥只有你有,无法伪造

工作原理

签名过程:
1. 计算数据的哈希值
   数据 → SHA256 → 哈希值

2. 用私钥加密哈希值
   哈希值 → [用私钥加密] → 签名值

3. 发送数据和签名
   数据 + 签名值 → 发送给对方

验证过程:
1. 计算收到数据的哈希值
   收到的数据 → SHA256 → 哈希值A

2. 用公钥解密签名值
   签名值 → [用公钥解密] → 哈希值B

3. 对比两个哈希值
   哈希值A == 哈希值B?
     ├── 相同 → 签名有效 ✅
     └── 不同 → 签名无效 ❌

代码示例:RSA数字签名

from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256

# 1. 生成密钥对
key = RSA.generate(2048)
private_key = key
public_key = key.publickey()

# 2. 签名(用私钥)
data = b"Hello, World!"
hash_obj = SHA256.new(data)
signature = pkcs1_15.new(private_key).sign(hash_obj)

print(f"原文: {data}")
print(f"签名: {signature.hex()}")

# 3. 验证签名(用公钥)
try:
    hash_obj = SHA256.new(data)
    pkcs1_15.new(public_key).verify(hash_obj, signature)
    print("✅ 签名验证成功")
except:
    print("❌ 签名验证失败")

# 4. 篡改数据后验证
tampered_data = b"Hello, World?"
try:
    hash_obj = SHA256.new(tampered_data)
    pkcs1_15.new(public_key).verify(hash_obj, signature)
    print("✅ 签名验证成功")
except:
    print("❌ 签名验证失败(数据被篡改)")

数字签名的作用

1. 身份认证

证明:这个数据确实是我发的
原理:只有我有私钥,只有我能生成这个签名

2. 数据完整性

证明:数据没有被篡改
原理:数据改一个字节,签名验证就会失败

3. 防抵赖

证明:你不能否认是你发的
原理:私钥只有你有,签名就是证据

1.7 它们之间的关系

完整的加密通信流程

场景:小明给小红发送加密消息

步骤1:小明用小红的公钥加密消息
消息 → [用小红的公钥加密] → 密文
(非对称加密,保证只有小红能看)

步骤2:小明用自己的私钥签名
消息 → SHA256 → 哈希值 → [用小明的私钥签名] → 签名
(数字签名,证明是小明发的)

步骤3:小明发送密文和签名
密文 + 签名 → 发送给小红

步骤4:小红验证签名
签名 → [用小明的公钥验证] → 验证通过 ✅
(确认是小明发的,数据未被篡改)

步骤5:小红解密消息
密文 → [用小红的私钥解密] → 消息
(只有小红能解密)

关系图

┌─────────────────────────────────────┐
│           加密通信体系               │
├─────────────────────────────────────┤
│                                     │
│  对称加密(AES)                     │
│    └── 用途:加密大量数据            │
│                                     │
│  非对称加密(RSA)                   │
│    ├── 用途1:交换对称密钥           │
│    └── 用途2:数字签名               │
│                                     │
│  哈希函数(SHA256)                  │
│    ├── 用途1:数据完整性校验         │
│    ├── 用途2:密码存储               │
│    └── 用途3:数字签名(签名哈希值) │
│                                     │
│  数字签名                            │
│    └── 组合:哈希函数 + 非对称加密   │
│                                     │
└─────────────────────────────────────┘

1.8 实际应用场景

场景1:HTTPS网站

1. 浏览器 → 服务器:你好,我要访问你
2. 服务器 → 浏览器:这是我的证书(包含公钥)
3. 浏览器验证证书(数字签名)
4. 浏览器生成对称密钥K
5. 浏览器 → 服务器:[用服务器公钥加密]对称密钥K
6. 服务器解密得到对称密钥K
7. 双方用对称密钥K加密通信

使用的技术:
- 非对称加密(RSA):交换对称密钥
- 对称加密(AES):加密数据传输
- 哈希函数(SHA256):验证数据完整性
- 数字签名:验证服务器身份

场景2:软件下载

1. 官网提供:软件 + SHA256哈希值
2. 用户下载软件
3. 用户计算下载文件的SHA256
4. 对比官网提供的SHA256
   ├── 相同 → 文件完整,未被篡改 ✅
   └── 不同 → 文件被篡改,不要安装 ❌

使用的技术:
- 哈希函数(SHA256):验证文件完整性

场景3:区块链

1. 交易数据 → SHA256 → 哈希值
2. 用私钥签名哈希值 → 签名
3. 广播:交易数据 + 签名
4. 其他节点用公钥验证签名
5. 验证通过 → 交易有效

使用的技术:
- 哈希函数(SHA256):计算区块哈希
- 数字签名(ECDSA):证明交易真实性

1.9 本章小结

核心要点

  1. 对称加密:一把钥匙,速度快,适合大数据
  2. 非对称加密:两把钥匙,安全性高,适合密钥交换
  3. 哈希函数:数据指纹,不可逆,用于完整性校验
  4. 数字签名:哈希+非对称加密,证明身份和防篡改

使用场景总结

需求
使用技术
原因

加密大量数据
对称加密(AES)
速度快

交换密钥
非对称加密(RSA)
安全

验证数据完整性
哈希函数(SHA256)
快速检测篡改

证明身份
数字签名
防抵赖

HTTPS通信
混合加密
兼顾安全和速度

记忆口诀

对称加密一把钥匙快,
非对称加密两把钥匙安全。
哈希函数算指纹,
数字签名证身份。

🤔 思考题

  1. 理解题:为什么HTTPS不直接用非对称加密传输所有数据,而要用混合加密?

  2. 场景题:如果你要发送一个1GB的视频给朋友,并且要保证:

  3. 只有朋友能看(加密)
  4. 朋友能确认是你发的(签名)
  5. 视频没有被篡改(完整性)

你会如何设计?用哪些加密技术?

  1. 对比题:SHA256和AES都能"加密"数据,它们有什么区别?

📚 下一章预告

第2章我们将学习多租户密钥体系设计
- 每个客户是否需要独立的公私钥对?
- 三种密钥体系方案的对比
- 如何选择适合你的方案?

准备好了吗?让我们继续前进!


本章关键词
- 对称加密(AES)
- 非对称加密(RSA)
- 哈希函数(SHA256)
- 数字签名
- 混合加密
- 公钥/私钥
- 数据完整性
- 身份认证

目录 最新
← 左侧翻上一屏 · 右侧翻下一屏 · 中间唤出菜单