python实现RSA算法

算法原理教学示例

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 算法原理参考:

RSA算法原理(一)-优快云博客

RSA算法原理(二)-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值