0Pricing
Cryptology Academy · 课时

Python 中的 RSA 与 ECDSA 密钥对

生成、序列化并使用 RSA 和 EC 密钥进行签名和加密

Python 中的 RSA 与 ECDSA 密钥对 是 CoddyKit 上的免费 Cryptology Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Cryptology Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Cryptology Academy 课程共包含 4 节课。

密钥对操作概览

Python 的 cryptography 库支持使用 RSA 和 ECDSA 生成、签名、验证、序列化及加载密钥。这些是 TLS 证书、代码签名和 JWT 的基础构件。

生成 RSA 密钥对

最低建议:为确保兼容性使用 2048 位;对于长期使用的密钥使用 4096 位:

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend

private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
    backend=default_backend()
)
public_key = private_key.public_key()
print("RSA key generated, size:", private_key.key_size, "bits")

使用 PSS 进行 RSA 签名

签名时始终使用 PSS 填充(不要使用 PKCS#1 v1.5):

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

message = b"document to sign"
signature = private_key.sign(
    message,
    padding.PSS(
        mgf=padding.MGF1(hashes.SHA256()),
        salt_length=padding.PSS.MAX_LENGTH
    ),
    hashes.SHA256()
)
print("RSA-PSS signature:", signature.hex()[:32], "...")

RSA 签名验证

验证失败时会引发 InvalidSignature:

from cryptography.exceptions import InvalidSignature

try:
    public_key.verify(
        signature,
        message,
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_LENGTH
        ),
        hashes.SHA256()
    )
    print("Signature valid!")
except InvalidSignature:
    print("Signature INVALID")

生成 ECDSA 密钥对

使用 NIST P-256(secp256r1)的 ECDSA 可以提供 128 位安全性,同时密钥比 RSA-3072 小得多:

from cryptography.hazmat.primitives.asymmetric import ec

private_key = ec.generate_private_key(ec.SECP256R1())
public_key = private_key.public_key()
print("EC private key generated on curve:", private_key.curve.name)

ECDSA 签名与验证

ECDSA 默认使用 DER 编码的签名:

from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography.exceptions import InvalidSignature

# Sign
sig = private_key.sign(b"my data", ec.ECDSA(hashes.SHA256()))
print("ECDSA signature bytes:", len(sig))

# Verify
try:
    public_key.verify(sig, b"my data", ec.ECDSA(hashes.SHA256()))
    print("ECDSA signature valid")
except InvalidSignature:
    print("Invalid")

将密钥序列化为 PEM

将密钥保存为 PEM 文件,以便存储或分发:

from cryptography.hazmat.primitives import serialization

# Private key — encrypted with passphrase
private_pem = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.BestAvailableEncryption(b"strong-passphrase")
)

# Public key — no encryption
public_pem = public_key.public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print(public_pem.decode()[:64])

从 PEM 加载密钥

将持久化的密钥重新加载为对象:

from cryptography.hazmat.primitives.serialization import (
    load_pem_private_key, load_pem_public_key
)

with open("ec_private.pem", "rb") as f:
    priv = load_pem_private_key(f.read(), password=b"strong-passphrase")

with open("ec_public.pem", "rb") as f:
    pub = load_pem_public_key(f.read())

print("Loaded EC key curve:", priv.curve.name)

ECDH 密钥协商

使用 ECDH 派生共享密钥,以便进行对称加密:

from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.hkdf import HKDF

alice_priv = ec.generate_private_key(ec.SECP256R1())
bob_priv = ec.generate_private_key(ec.SECP256R1())

# Alice computes shared secret
shared = alice_priv.exchange(ec.ECDH(), bob_priv.public_key())
aes_key = HKDF(hashes.SHA256(), 32, None, b"app-context").derive(shared)
print("Derived AES key:", aes_key.hex())

使用 OAEP 进行 RSA 加密

使用 RSA 加密小型数据载荷(例如 DEK)时,始终使用 OAEP:

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

# Encrypt with public key
ciphertext = public_key.encrypt(
    b"small secret",
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)

# Decrypt with private key
plaintext = private_key.decrypt(ciphertext, padding.OAEP(
    mgf=padding.MGF1(algorithm=hashes.SHA256()),
    algorithm=hashes.SHA256(), label=None
))
print("Decrypted:", plaintext)

选择 RSA 还是 ECDSA

ECDSA:签名更小(P-256 约为 71 字节,而 RSA-2048 约为 256 字节)、签名速度更快,安全级别相同。RSA:传统系统支持更广泛,理解模型更简单。对于新系统,请使用 ECDSA P-256 或 Ed25519。

知识检查

为什么数字签名应优先使用 RSA-PSS,而不是 PKCS#1 v1.5?

课程回顾

RSA 请使用 rsa.generate_private_key,ECDSA 请使用 ec.generate_private_key。使用 PSS(RSA)或 ECDSA + SHA-256 进行签名。使用 PKCS8 格式将密钥序列化为 PEM,并使用密码短语加密。使用 ECDH 进行密钥协商。对于新系统,请优先使用 ECDSA P-256 或 Ed25519。

常见问题解答

「Python 中的 RSA 与 ECDSA 密钥对」课时是免费的吗?

是的 — 「Python 中的 RSA 与 ECDSA 密钥对」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Cryptology Academy 课程的其余内容,请升级到 CoddyKit PRO。 Cryptology Academy 课程共包含 4 节课。

「Python 中的 RSA 与 ECDSA 密钥对」这节课中我会学到什么?

生成、序列化并使用 RSA 和 EC 密钥进行签名和加密 你通过在浏览器中直接运行的动手代码来练习 Cryptology Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Cryptology Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Cryptology Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「Python 中的 RSA 与 ECDSA 密钥对」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Cryptology Academy 课中编写并运行代码吗?

能。每节 Cryptology Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Python 密码学库概览
  2. 在 Python 中使用 AES-GCM 加密与解密
  3. Python 中的 RSA 与 ECDSA 密钥对
  4. 常见 Python 加密陷阱与安全模式
← 返回 Cryptology Academy