算法原理教学示例
import random
import math
'''
RSA算法原理参考:
https://blog.youkuaiyun.com/andy0ma/article/details/147738671?spm=1001.2014.3001.5502
https://blog.youkuaiyun.com/andy0ma/article/details/147739337?spm=1011.2415.3001.5331
https://blog.youkuaiyun.com/qq_45638953/article/details/146348195
以下代码仅用于教学,省略了填充、大素数生成优化等关键安全细节
'''
def is_prime(n, k=5):
"""Miller-Rabin 素性测试"""
if n <= 1:
return False
for p in [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]:
if n % p == 0:
return n == p
d = n - 1
s = 0
while d % 2 == 0:
d //= 2
s += 1
for _ in range(k):
a = random.randint(2, n - 2)
x = pow(a, d, n)
if x == 1 or x == n - 1:
continue
for __ in range(s - 1):
x = pow(x, 2, n)
if x == n - 1:
break
else:
return False
return True
def generate_prime(bits=512):
"""生成大素数"""
while True:
p = random.getrandbits(bits)
if is_prime(p):
return p
def extended_gcd(a, b):
"""扩展欧几里得算法求模逆元"""
if b == 0:
return a, 1, 0
else:
g, x, y = extended_gcd(b, a % b)
return g, y, x - (a // b) * y
def generate_keys(bits=512):
"""生成RSA密钥对"""
p = generate_prime(bits // 2)
q = generate_prime(bits // 2)
n = p * q
phi = (p - 1) * (q - 1)
# 选择公钥指数e
e = 65537
while math.gcd(e, phi) != 1:
e = random.randint(2, phi - 1)
# 计算私钥指数d
_, d, _ = extended_gcd(e, phi)
d = d % phi
return (e, n), (d, n)
def encrypt(pub_key, plaintext):
"""加密"""
e, n = pub_key
m = int.from_bytes(plaintext.encode(), 'big')
assert m < n, "明文过长"
return pow(m, e, n)
def decrypt(priv_key, ciphertext):
"""解密"""
d, n = priv_key
m = pow(ciphertext, d, n)
return m.to_bytes((m.bit_length() + 7) // 8, 'big').decode()
# 以下代码仅用于教学,省略了填充、大素数生成优化等关键安全细节
# 示例用法
public_key, private_key = generate_keys(1024)
print("public_key:", public_key)
print("private_key:", private_key)
message = "Hello, RSA!"
print("原始消息:", message)
# 加密
cipher = encrypt(public_key, message)
print("密文:", hex(cipher))
# 解密
decrypted = decrypt(private_key, cipher)
print("解密结果:", decrypted)
用 Crypto 中 RSA 库实现代码:
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
# 1. 密钥生成
key = RSA.generate(2048) # 2048位密钥
private_key = key.export_key()
public_key = key.publickey().export_key()
print("private_key: ", private_key)
print("public_key: ", public_key)
# 2. 加密
public_key_obj = RSA.import_key(public_key)
cipher = PKCS1_OAEP.new(public_key_obj)
message = b"Secret Message"
ciphertext = cipher.encrypt(message)
print("原始消息 message: ", message)
print("ciphertext: ", ciphertext)
# 3. 解密
private_key_obj = RSA.import_key(private_key)
cipher = PKCS1_OAEP.new(private_key_obj)
decrypted = cipher.decrypt(ciphertext)
print("解密后的数据 data:", decrypted)
用cryptography 库代码示例:
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
# 密钥生成(2048位)
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
public_key = private_key.public_key()
print("private_key :", private_key.private_bytes)
print("public_key :", public_key.public_bytes)
# 加密(使用OAEP填充)
message = b"Top Secret Data"
ciphertext = public_key.encrypt(
message,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
print("message :", message)
print("Ciphertext (Hex):", ciphertext.hex())
# 解密
plaintext = private_key.decrypt(
ciphertext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
print("Decrypted:", plaintext.decode())
# 签名与验证
signature = private_key.sign(
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
public_key.verify(
signature,
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
print("Signature Valid!")
关键安全注意事项
生产环境必须使用标准库:自制实现缺少随机填充(抵抗选择密文攻击),时序攻击防护,密钥安全存储机制等
消息长度限制:RSA 只能加密比模数短的数据,实际使用时:
# 加密长数据应使用混合加密:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding as sym_padding
# 1. 生成随机AES密钥
aes_key = os.urandom(32)
# 2. 用RSA加密AES密钥
encrypted_key = public_key.encrypt(aes_key, padding.OAEP(...))
# 3. 用AES加密实际数据
cipher = Cipher(algorithms.AES(aes_key), modes.GCM(...))
密钥存储规范
# 保存密钥到PEM文件
from cryptography.hazmat.primitives import serialization
# 私钥保存(密码保护)
pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.BestAvailableEncryption(b'password')
)
with open('private.pem', 'wb') as f:
f.write(pem)
# 公钥保存
pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
性能对比(测试数据)
| 操作 | 标准库 (2048位) | 纯Python (1024位) |
| 密钥生成 | 0.3s | 12.8s |
| 加密 (1KB数据) | 0.01s | 1.4s |
| 解密 | 0.05s | 3.2s |
cyptography和crypto的区别请参考:
Python3中cryptography与crypto 的区别-优快云博客
RSA 算法原理参考:
2万+

被折叠的 条评论
为什么被折叠?



