Skip to content

密码学基础与应用 — 对称/非对称加密、哈希、数字签名、PKI

Published:
15 min read

密码学是网络安全的基石。从你每天浏览网页时浏览器地址栏的那把小锁,到电子支付、数字签名和区块链,密码学技术无处不在地保障着数字世界的安全运转。然而,密码学并非遥不可及的数学黑箱——理解其核心原理和正确使用方式,是每一个安全从业者和开发者的必备素养。本文将系统讲解对称加密、非对称加密、哈希函数、数字签名和 PKI 体系等密码学核心概念,并通过实际命令演示其应用。

对称加密

对称加密是最直观的加密方式:加密和解密使用同一把密钥。发送方用密钥加密明文,接收方用相同的密钥解密密文。

核心算法

OpenSSL 对称加密实战

# 使用 AES-256-CBC 加密文件
openssl enc -aes-256-cbc -salt -pbkdf2 -iter 100000 \
  -in plaintext.txt -out encrypted.bin
# 系统会提示输入加密密码

# 解密文件
openssl enc -aes-256-cbc -d -pbkdf2 -iter 100000 \
  -in encrypted.bin -out decrypted.txt

# 使用指定密钥和 IV 加密(非交互式)
openssl enc -aes-256-cbc -K $(openssl rand -hex 32) \
  -iv $(openssl rand -hex 16) \
  -in plaintext.txt -out encrypted.bin

# 查看支持的对称加密算法列表
openssl enc -list

加密模式

对称加密的工作模式决定了如何处理超过一个块大小的数据:

对称加密的挑战

对称加密的最大挑战是密钥分发问题——如何在通信双方之间安全地共享密钥?如果密钥在传输过程中被截获,整个加密体系就会崩塌。这正是非对称加密要解决的核心问题。

非对称加密

非对称加密使用一对数学上相关的密钥:公钥(Public Key)和私钥(Private Key)。公钥公开发布,私钥严格保密。用公钥加密的数据只能用对应的私钥解密,反之亦然。

核心算法

OpenSSL 非对称加密实战

# ===== RSA 密钥操作 =====

# 生成 4096 位 RSA 私钥
openssl genrsa -out private_key.pem 4096

# 从私钥导出公钥
openssl rsa -in private_key.pem -pubout -out public_key.pem

# 查看密钥信息
openssl rsa -in private_key.pem -text -noout

# 使用公钥加密文件(RSA 直接加密有长度限制,适合加密小数据如对称密钥)
openssl rsautl -encrypt -inkey public_key.pem -pubin \
  -in secret.txt -out secret.enc

# 使用私钥解密
openssl rsautl -decrypt -inkey private_key.pem \
  -in secret.enc -out secret_decrypted.txt

# ===== ECC 密钥操作 =====

# 查看支持的椭圆曲线
openssl ecparam -list_curves

# 生成 ECC 私钥(使用 P-256 曲线)
openssl ecparam -genkey -name prime256v1 -out ec_private.pem

# 导出 ECC 公钥
openssl ec -in ec_private.pem -pubout -out ec_public.pem

# 查看 ECC 密钥信息
openssl ec -in ec_private.pem -text -noout

非对称加密的应用场景

哈希函数

哈希函数(Hash Function)将任意长度的输入映射为固定长度的输出(哈希值/摘要),并且具有以下特性:

常用哈希算法

算法输出长度安全状态适用场景
MD5128 位已不安全,存在碰撞攻击仅用于文件校验(非安全场景)
SHA-1160 位已不安全,Google 实现了碰撞逐步淘汰中
SHA-256256 位安全数字签名、证书、区块链
SHA-3可变安全新一代标准,与 SHA-2 并行使用
BLAKE2可变安全高性能场景

哈希函数实战

# 计算文件的各种哈希值
md5sum document.pdf
sha1sum document.pdf
sha256sum document.pdf

# 使用 openssl 计算哈希
openssl dgst -sha256 document.pdf
openssl dgst -sha3-256 document.pdf

# 比较两个文件是否一致
sha256sum file1.txt file2.txt

# 验证下载文件的完整性
echo "a]已知的SHA256哈希值  downloaded_file.iso" | sha256sum -c -

# 生成随机数据的哈希(可用于生成令牌)
openssl rand -hex 32 | sha256sum

密码存储中的哈希

直接使用 MD5 或 SHA-256 存储密码是不安全的,因为攻击者可以使用彩虹表进行查表攻击。应当使用专门设计的密码哈希函数:

# Python 中安全的密码哈希存储
import bcrypt

# 哈希密码(bcrypt 自动生成盐值)
password = b"user_password_123"
salt = bcrypt.gensalt(rounds=12)  # 工作因子为 12
hashed = bcrypt.hashpw(password, salt)

print(f"哈希结果: {hashed}")
# 输出类似: $2b$12$LJ3m4ys3Lg...

# 验证密码
if bcrypt.checkpw(password, hashed):
    print("密码验证通过")
else:
    print("密码错误")
# 使用 argon2(密码哈希竞赛冠军)
from argon2 import PasswordHasher

ph = PasswordHasher(
    time_cost=3,       # 迭代次数
    memory_cost=65536,  # 内存消耗(KB)
    parallelism=4       # 并行线程数
)

# 哈希密码
hash_value = ph.hash("user_password_123")

# 验证密码
try:
    ph.verify(hash_value, "user_password_123")
    print("密码正确")
except Exception:
    print("密码错误")

数字签名

数字签名结合了哈希函数和非对称加密,用于验证数据的完整性和发送者的身份。

签名流程

  1. 发送方对原始数据计算哈希摘要
  2. 用发送方的私钥对哈希摘要进行加密(签名)
  3. 将原始数据和签名一起发送给接收方

验证流程

  1. 接收方用发送方的公钥解密签名,得到哈希摘要 A
  2. 接收方对收到的原始数据计算哈希摘要 B
  3. 比较摘要 A 和摘要 B,如果一致则说明数据未被篡改且确实来自发送方
# 使用 OpenSSL 进行数字签名

# 1. 对文件进行签名
openssl dgst -sha256 -sign private_key.pem -out signature.bin document.pdf

# 2. 验证签名
openssl dgst -sha256 -verify public_key.pem -signature signature.bin document.pdf
# 输出 "Verified OK" 表示验证通过

# 使用 ECC 密钥签名(更高效)
openssl dgst -sha256 -sign ec_private.pem -out sig_ecc.bin document.pdf
openssl dgst -sha256 -verify ec_public.pem -signature sig_ecc.bin document.pdf

PKI 体系

PKI(Public Key Infrastructure,公钥基础设施)是一套用于管理数字证书和公钥加密的框架体系,解决了”如何信任公钥确实属于其声称的所有者”这一核心问题。

核心组件

# 查看网站的 SSL/TLS 证书信息
openssl s_client -connect www.example.com:443 -showcerts

# 查看证书的详细内容
openssl x509 -in certificate.pem -text -noout

# 验证证书链
openssl verify -CAfile ca_bundle.pem certificate.pem

# 生成自签名证书(测试用途)
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \
  -days 365 -nodes \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=example.com"

# 使用 Let's Encrypt 获取免费证书(通过 certbot)
sudo certbot certonly --standalone -d example.com

TLS/SSL 握手过程

TLS(Transport Layer Security)是保障互联网通信安全的核心协议。TLS 握手的目的是:身份验证、密钥协商和建立加密通道。

TLS 1.3 握手简化流程

TLS 1.3 相比 1.2 大幅简化了握手过程,仅需 1-RTT(一次往返)即可完成:

  1. Client Hello:客户端发送支持的密码套件列表、随机数和密钥共享参数
  2. Server Hello + 证书 + 签名:服务器选择密码套件,发送证书和密钥共享参数,并用私钥签名
  3. 客户端验证:验证服务器证书和签名,双方各自计算出相同的会话密钥
  4. 加密通信开始:使用协商的对称密钥加密后续所有通信
# 测试目标服务器支持的 TLS 版本和密码套件
openssl s_client -connect example.com:443 -tls1_3

# 查看完整的握手过程
openssl s_client -connect example.com:443 -msg -debug

# 使用 nmap 扫描 TLS 配置
nmap --script ssl-enum-ciphers -p 443 example.com

# 测试是否存在已知 TLS 漏洞
nmap --script ssl-heartbleed,ssl-poodle -p 443 example.com

TLS 最佳实践

安全建议

  1. 选择合适的算法:对称加密优先选择 AES-256-GCM,非对称加密推荐 ECC(P-256 或 Curve25519),哈希函数使用 SHA-256 或 SHA-3
  2. 密码存储必须使用专用算法:使用 bcrypt、Argon2 或 scrypt,绝不直接使用 MD5/SHA 存储密码
  3. 密钥管理至关重要:使用专业的密钥管理系统(KMS),定期轮换密钥,妥善保管私钥
  4. 不要自己发明加密算法:使用经过广泛验证的标准算法和成熟的加密库
  5. 保持更新:关注密码学领域的最新进展,及时淘汰不安全的算法和协议
  6. 关注量子计算威胁:了解后量子密码学(Post-Quantum Cryptography)的发展,为未来的迁移做准备

总结

密码学是网络安全的数学基础。对称加密以其高效的性能承担了大量数据的加密工作,非对称加密巧妙地解决了密钥分发和身份认证问题,哈希函数为数据完整性提供了可靠保障,数字签名结合了哈希和非对称加密实现了不可否认性,而 PKI 体系则构建了互联网信任的基础设施。TLS 协议将这些密码学原语有机组合,为每一次网络通信提供机密性、完整性和身份认证保障。正确理解和使用这些密码学工具,是构建安全系统的根本。