现代密码学 | RSA 算法—附py代码

Rivest-Shamir-Adleman (RSA),RSA 算法以它的创造者罗纳德·李维斯特、阿迪·沙米尔和伦纳德·阿德曼的名字命名,他们于 1977 年首次披露了这一算法,被视为最具影响力的加密方法之一。

这种基于公钥加密的加密技术构成了互联网上数据安全传输的基础。RSA 算法不仅改变了安全通信的实施方式,还为数字安全领域的多项突破奠定了基础。

RSA 算法依赖于大质数因式分解的数学难题。RSA 的安全性在于找出生成给定大合数的两个大质数这一难题,有时也称为质因数分解。随着数字规模的增大,这个问题的计算复杂度呈指数级增长,这确保了 RSA 算法的安全性。

密钥生成

RSA 算法始于密钥的生成。该过程包含以下几个步骤:

  1. 素数和模数的选择。随机选取两个大素数 p 和 q。这两个数的乘积 n = p × q 用作公钥和私钥的模数。n 的值必须足够大以确保安全性,通常有数百位之长。
  2. 欧拉函数的计算。欧拉函数 φ(n) 的计算公式为 φ(n) = (p - 1) × (q - 1)。此值对于确定公钥和私钥至关重要。
  3. 公钥生成。公钥由模数 n 和公指数 e 组成,e 通常是像 3 或 65537 这样的小质数,选择时要确保其与 φ(n) 互质。
  4. 私钥生成。私钥是从相同的模数生成的。请提供需要翻译的原文。n 以及一个私钥指数 d,它是 ee 模 φ(n) 的模反元素。

加密与解密涉及模运算:

  1. 加密。发送方将明文消息转换为数字格式(明文整数 m)。然后使用以下公式生成密文 c:c = m^e mod n 。
  2. 解密。接收方使用私钥和公式 m = cd mod n 将密文还原为明文。

此过程确保只有私钥持有者能够解密消息,从而为通信提供保密性和安全性。

py代码示例,包含密钥生成、加密和解密功能(仅供参考)

import random
import math
from math import gcd
from typing import Tuple

def is_prime(n: int, k: int = 5) -> bool:
    """米勒-拉宾素性测试"""
    if n <= 1 or n == 4:
        return False
    if n <= 3:
        return True
    if n % 2 == 0:
        return False
    
    # 将n-1表示为d*2^r
    d = n - 1
    r = 0
    while d % 2 == 0:
        d //= 2
        r += 1
    
    # 进行k次测试
    for _ in range(k):
        a = random.randint(2, n - 2)
        x = pow(a, d, n)
        if x == 1 or x == n - 1:
            continue
            
        composite = True
        for __ in range(r - 1):
            x = pow(x, 2, n)
            if x == n - 1:
                composite = False
                break
                
        if composite:
            return False
            
    return True

def generate_prime(bits: int) -> int:
    """生成指定位数的大素数"""
    while True:
        num = random.getrandbits(bits)
        # 确保是奇数且位数正确
        num |= (1 << bits - 1) | 1
        if is_prime(num):
            return num

def extended_gcd(a: int, b: int) -> Tuple[int, int, int]:
    """扩展欧几里得算法"""
    if b == 0:
        return a, 1, 0
    else:
        g, x1, y1 = extended_gcd(b, a % b)
        g, x, y = g, y1, x1 - (a // b) * y1
        return g, x, y

def mod_inverse(a: int, m: int) -> int:
    """计算模逆元"""
    g, x, y = extended_gcd(a, m)
    if g != 1:
        raise ValueError(f"{a} 在模 {m} 下没有逆元")
    return x % m

def generate_keys(key_size: int = 1024) -> Tuple[Tuple[int, int], Tuple[int, int]]:
    """
    生成RSA密钥对
    :param key_size: 密钥位数
    :return: 公钥(e, n)和私钥(d, n)
    """
    # 生成两个不同的大素数
    p = generate_prime(key_size // 2)
    q = generate_prime(key_size // 2)
    while p == q:
        q = generate_prime(key_size // 2)
    
    # 计算模数n和欧拉函数φ(n)
    n = p * q
    phi = (p - 1) * (q - 1)
    
    # 选择公钥指数e (65537是常用值)
    e = 65537
    while gcd(e, phi) != 1:
        e = random.randint(2, phi - 1)
    
    # 计算私钥指数d
    d = mod_inverse(e, phi)
    
    return (e, n), (d, n)

def rsa_encrypt(public_key: Tuple[int, int], plaintext: int) -> int:
    """
    RSA加密
    :param public_key: 公钥(e, n)
    :param plaintext: 要加密的整数
    :return: 密文整数
    """
    e, n = public_key
    if plaintext < 0 or plaintext >= n:
        raise ValueError("明文必须在范围 [0, n-1] 内")
    return pow(plaintext, e, n)

def rsa_decrypt(private_key: Tuple[int, int], ciphertext: int) -> int:
    """
    RSA解密
    :param private_key: 私钥(d, n)
    :param ciphertext: 要解密的整数
    :return: 明文整数
    """
    d, n = private_key
    if ciphertext < 0 or ciphertext >= n:
        raise ValueError("密文必须在范围 [0, n-1] 内")
    return pow(ciphertext, d, n)

def text_to_int(text: str) -> int:
    """将文本转换为整数"""
    return int.from_bytes(text.encode('utf-8'), 'big')

def int_to_text(num: int) -> str:
    """将整数转换回文本"""
    # 计算需要的字节数
    byte_length = (num.bit_length() + 7) // 8
    bytes_data = num.to_bytes(byte_length, 'big')
    return bytes_data.decode('utf-8', errors='replace')

def rsa_encrypt_text(public_key: Tuple[int, int], text: str) -> int:
    """加密文本"""
    return rsa_encrypt(public_key, text_to_int(text))

def rsa_decrypt_text(private_key: Tuple[int, int], ciphertext: int) -> str:
    """解密文本"""
    return int_to_text(rsa_decrypt(private_key, ciphertext))

# 示例测试
if __name__ == "__main__":
    print("生成RSA密钥对...")
    public_key, private_key = generate_keys(1024)
    print(f"公钥 (e, n): ({public_key[0]}, {public_key[1]})")
    print(f"私钥 (d, n): ({private_key[0]}, {private_key[1]})")
    
    # 原始消息
    message = "Hello, RSA! 你好,RSA!"
    print(f"\n原始消息: {message}")
    
    # 加密
    ciphertext = rsa_encrypt_text(public_key, message)
    print(f"\n加密后的整数: {ciphertext}")
    
    # 解密
    decrypted_message = rsa_decrypt_text(private_key, ciphertext)
    print(f"\n解密后的消息: {decrypted_message}")
    
    # 验证加解密一致性
    assert message == decrypted_message, "加解密结果不一致!"
    print("\n验证成功: 解密消息与原始消息一致")

运行结果:

在这里插入图片描述

代码说明:

generate_keys(): 生成RSA密钥对(公钥和私钥)

rsa_encrypt() / rsa_decrypt(): 加密和解密整数

rsa_encrypt_text() / rsa_decrypt_text(): 加密和解密文本

辅助函数:

is_prime(): 使用米勒-拉宾算法检测素数

generate_prime(): 生成指定位数的大素数

mod_inverse(): 计算模逆元(使用扩展欧几里得算法)

text_to_int()/int_to_text(): 文本与整数之间的转换

RSA 算法的实际应用十分广泛。它用于保护网络浏览器、电子邮件、虚拟专用网络(VPN)以及许多其他形式的数字通信的安全。除了加密之外,RSA 还能实现数字签名,这对于数字交易中的身份验证和不可否认性至关重要。

尽管 RSA 具有一定优势,但它也面临着诸如计算资源不断增强以及量子计算发展等挑战。理论上,量子计算机能够高效地解决质因数分解问题,从而威胁到 RSA 的安全基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Turbo正则

如果对您有用请我喝杯咖啡吧~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值