Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

cryptography 基础教程

下面给你一份 超实用 + 清晰分层的《Python cryptography 库 教程》,涵盖常用功能、最佳实践、常见错误处理、生产环境建议。内容基于最新版(cryptography ≥ 42+)风格,保证你马上能用。

🧩 Python cryptography 库教程

适合:后端开发者 / 安全开发 / Token / 加密存储 / HTTPS / JWT / 非对称加密

目录

  1. 📦 安装
  2. 🔐 高层(Fernet)对称加密
  3. 🗝 低层(Hazmat)AES-GCM
  4. 🔑 非对称 RSA(生成密钥 / 加解密 / 签名)
  5. 🔑 非对称 ECC(更快、更安全)
  6. 🧾 哈希(SHA256、HMAC)
  7. 🎫 JWT 自建签名系统(不依赖第三方库)
  8. 📁 文件加密
  9. 🛡 证书、TLS 工具(X509)
  10. 🧨 错误处理
  11. 🏭 生产环境最佳实践

1. 安装

pip install cryptography

2. 🔐 Fernet(最简单可靠的对称加密)

Fernet 封装了 AES + HMAC,几乎是“拿来就用”的安全方案。

生成密钥

from cryptography.fernet import Fernet

key = Fernet.generate_key()
print(key)

加密 & 解密

from cryptography.fernet import Fernet

key = Fernet.generate_key()
f = Fernet(key)

token = f.encrypt(b"hello world")
plain = f.decrypt(token)

print(token, plain)

特点

  • AES128 + HMAC-SHA256 组合
  • 默认提供时间戳
  • 易用、安全、适合绝大部分“加密字符串/敏感配置”场景

3. 🧪 Hazmat 层 AES-GCM(高级对称加密)

适合你需要:

  • 自己处理 IV / tag
  • 加密二进制数据
  • 与其他语言互通(AES-GCM 是标准)

AES-GCM 示例

import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

key = AESGCM.generate_key(bit_length=256)
aesgcm = AESGCM(key)

nonce = os.urandom(12)  # 推荐 12 字节
data = b"secret message"
aad = b"authenticated data"

ciphertext = aesgcm.encrypt(nonce, data, aad)
plaintext = aesgcm.decrypt(nonce, ciphertext, aad)

print(ciphertext, plaintext)

4. 🔑 RSA(生成密钥 / 加密 / 签名)

生成 RSA 密钥

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization

private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048
)

pem = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption(),
)

print(pem.decode())

RSA 加密 & 解密(OAEP)

from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes

public_key = private_key.public_key()

ciphertext = public_key.encrypt(
    b"hello",
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)

plaintext = private_key.decrypt(
    ciphertext,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)

5. 🧩 ECC(更快且更强的非对称加密)

推荐 Curve25519 / Ed25519。

Ed25519 签名

from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey

private_key = Ed25519PrivateKey.generate()
public_key = private_key.public_key()

msg = b"hello"

signature = private_key.sign(msg)
public_key.verify(signature, msg)

优点:

  • 密钥更短
  • 速度比 RSA 快
  • 非常适合签名(JWT、API 签名)

6. 🧾 哈希与 HMAC

SHA256

from cryptography.hazmat.primitives import hashes

digest = hashes.Hash(hashes.SHA256())
digest.update(b"hello")
print(digest.finalize().hex())

HMAC

from cryptography.hazmat.primitives.hmac import HMAC

h = HMAC(b"secret-key", hashes.SHA256())
h.update(b"hello")
tag = h.finalize()
print(tag.hex())

7. 🎫 自建 JWT(HS256 / RS256 / EdDSA)

不依赖 PyJWT,用 cryptography 原生实现。

HS256(对称)

import base64
import json
from cryptography.hazmat.primitives import hmac, hashes

def b64(x):
    return base64.urlsafe_b64encode(x).rstrip(b'=')

header = b64(json.dumps({"alg": "HS256", "typ": "JWT"}).encode())
payload = b64(json.dumps({"uid": 1}).encode())

msg = header + b"." + payload

h = hmac.HMAC(b"secret", hashes.SHA256())
h.update(msg)
sig = b64(h.finalize())

jwt = msg + b"." + sig
print(jwt.decode())

8. 📁 文件加密(AES-GCM)

import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

key = AESGCM.generate_key(256)
aes = AESGCM(key)

with open("input.bin", "rb") as f:
    data = f.read()

nonce = os.urandom(12)
ciphertext = aes.encrypt(nonce, data, None)

with open("input.bin.enc", "wb") as f:
    f.write(nonce + ciphertext)

9. 🛡 证书(X509)生成

生成简易自签证书

import datetime
from cryptography.x509 import NameOID
from cryptography import x509
from cryptography.hazmat.primitives import hashes

subject = issuer = x509.Name([
    x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
    x509.NameAttribute(NameOID.COMMON_NAME, u"test.local"),
])

cert = (
    x509.CertificateBuilder()
    .subject_name(subject)
    .issuer_name(issuer)
    .public_key(private_key.public_key())
    .serial_number(x509.random_serial_number())
    .not_valid_before(datetime.datetime.utcnow())
    .not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=365))
    .sign(private_key, hashes.SHA256())
)

print(cert.public_bytes(serialization.Encoding.PEM).decode())

10. 🧨 常见错误处理

错误 原因 解决
InvalidTag AES-GCM 解密失败(密钥/nonce/AAD 错误) 保证 nonce 不重复 / 验证 AAD
UnsupportedAlgorithm 使用过时算法 使用 SHA256+ / AES-GCM
ValueError: Encryption/decryption failed RSA 填充不匹配 使用 OAEP,避免 PKCS1v1.5

11. 🏭 生产环境最佳实践

  • 对称加密:优先使用 AES-GCM
  • 简单字符串加密:Fernet
  • 签名:Ed25519
  • 公钥加密:RSA-OAEP 或 X25519

密钥存储放在:

  • Kubernetes secret
  • Vault
  • 环境变量 + 文件挂载

❌ 不要:

  • 不要重复使用 AES-GCM nonce
  • 不要使用 DES / RC4 / ECB
  • 不要把私钥提交到 Git