2. RSA算法原理

RSA算法是1977年由Ron Rivest、Adi Shamir和Leonard Adleman共同提出的非对称加密算法,其安全性基于大整数因子分解的数学困难问题。RSA是当前应用最广泛的公钥密码体制之一,被用于SSL/TLS、数字签名、安全电子邮件等场景。

2.1 RSA密钥生成

RSA密钥生成的核心步骤包括大素数选取、模数计算、公私钥指数确定。以下为完整流程:

步骤 操作 数学表达 说明
1 选取两个大素数 p, q 通常为512~2048位随机素数,需通过Miller-Rabin素性测试
2 计算模数 n = p × q n的二进制长度即为RSA密钥长度(如2048位)
3 计算欧拉函数 φ(n) = (p-1)(q-1) 用于后续指数互素条件判断
4 选取公钥指数 e 满足 1 < e < φ(n) 且 gcd(e, φ(n)) = 1,常用值 65537
5 计算私钥指数 d ≡ e⁻¹ mod φ(n) 使用扩展欧几里得算法求解乘法逆元
6 输出密钥对 公钥 (n, e),私钥 (n, d) p, q, φ(n) 必须安全销毁或保密存储
工程实践提示:公钥指数 e 通常固定为 65537(0x10001),因其二进制表示中只有两个1,可大幅提升加密运算效率,同时保持足够的安全性。
RSA密钥生成流程 RSA密钥生成流程 ① 选取大素数 p, q ② 计算模数 n = p × q ③ 计算 φ(n) = (p-1)(q-1) ④ 选取公钥指数 e(互素条件) ⑤ 计算私钥指数 d ≡ e⁻¹ mod φ(n) ⑥ 输出:公钥 (n, e) | 私钥 (n, d) ⚠ 销毁 p, q, φ(n) 仅保留公钥与私钥

2.2 大素数选取与素性测试

大素数选取是RSA密钥生成的第一步,也是最耗时的步骤。实际工程中采用随机生成+概率素性测试的策略:

  • 随机生成候选数:使用密码学安全随机数生成器(CSPRNG)生成长度为 k 位的奇数
  • 小素数筛除:用前几百个小素数(如3,5,7,11,...)快速筛除合数,减少后续计算量
  • Miller-Rabin素性测试:对通过筛除的候选数进行多次测试,错误概率 ≤ 4-t(t为测试轮数)
安全参数建议:对于2048位RSA密钥,p和q各约1024位。Miller-Rabin测试轮数推荐为64轮(NIST SP 800-89标准),此时合数被误判为素数的概率低于 2-128。

2.3 加密与解密过程

RSA加密和解密基于模幂运算,将明文/密文视为整数,在模 n 下进行指数运算。消息 m 必须满足 0 ≤ m < n。

操作 公式 输入 输出
加密 c = me mod n 明文 m,公钥 (n, e) 密文 c
解密 m = cd mod n 密文 c,私钥 (n, d) 明文 m

解密正确性由欧拉定理保证:若 c ≡ me (mod n),则 cd ≡ med ≡ m1+kφ(n) ≡ m (mod n)。

RSA加密解密流程 RSA加密与解密流程 发送方 持有明文 m 加密运算 c = me mod n 公钥 (n, e) 密文 c(公开信道) 接收方 恢复明文 m 解密运算 m = cd mod n 私钥 (n, d) 保密 ⚠ 加密使用公钥,解密使用私钥;私钥必须严格保密,公钥可公开分发 密文在公开信道传输,即使被截获,无私钥也无法解密

2.4 RSA的安全性分析

RSA的安全性建立在以下数学难题之上,同时需防范多种攻击向量:

2.4.1 安全基础

  • 大整数因子分解问题(IFP):给定 n = p×q,求 p 和 q。目前没有多项式时间算法,2048位RSA在可预见的未来被认为是安全的
  • RSA问题(RSAP):给定 (n, e, c),求 m 使得 c ≡ me mod n。若IFP可解,则RSAP可解;反之不一定成立

2.4.2 主要攻击类型与防御

攻击类型 攻击原理 防御措施
因子分解攻击 使用数域筛法(NFS)分解 n 密钥长度 ≥ 2048位;p和q位长相近但差值足够大
共模攻击 同一 n 下不同 e 加密同一消息 不同用户使用不同 n,禁止共享模数
低指数攻击 e 过小(如 e=3)且 m 较小时可开方 使用 e=65537;对消息进行OAEP填充
时序攻击 通过解密时间差异推断私钥位 使用常数时间模幂运算或盲化技术
选择密文攻击 利用解密预言机获取信息 使用OAEP/OAEP+填充方案,确保密文不可延展
安全警告:教科书式RSA(无填充)存在严重安全隐患,包括确定性加密、密文可延展性、小指数攻击等。实际应用中必须使用OAEP(最优非对称加密填充)或RSAES-PKCS1-v1_5等安全填充方案。

2.4.3 密钥长度安全等级

密钥长度(位) 安全等级 推荐使用场景 预计安全年限
1024 已不安全 已废弃,不应使用 —
2048 当前标准 一般商业应用、TLS证书 至2030年
3072 长期安全 高安全需求、政府级应用 至2040年
4096 极高安全 根证书、长期密钥 至2050年+
性能权衡:密钥长度每增加一倍,加密/解密时间约增加6~8倍。2048位RSA在主流CPU上单次解密约需1~5ms,4096位则需5~30ms。建议在安全性与性能之间选择2048或3072位。

2.5 RSA算法代码示例

以下为Python实现的RSA密钥生成、加密与解密核心逻辑(仅用于教学演示,实际生产环境应使用cryptography库):

import random
from math import gcd

def generate_prime(bits):
    """生成指定位数的素数(简化版)"""
    while True:
        # 生成随机奇数
        candidate = random.getrandbits(bits) | (1 << (bits-1)) | 1
        # Miller-Rabin素性测试(简化:5轮)
        if is_probable_prime(candidate, 5):
            return candidate

def is_probable_prime(n, k):
    """Miller-Rabin素性测试"""
    if n < 2: return False
    if n == 2 or n == 3: return True
    if n % 2 == 0: return False
    
    r, d = 0, n - 1
    while d % 2 == 0:
        r += 1
        d //= 2
    
    for _ in range(k):
        a = random.randrange(2, n - 2)
        x = pow(a, d, n)
        if x == 1 or x == n - 1:
            continue
        for _ in range(r - 1):
            x = pow(x, 2, n)
            if x == n - 1:
                break
        else:
            return False
    return True

def rsa_keygen(bits=2048):
    """RSA密钥生成"""
    # 选取两个大素数
    p = generate_prime(bits // 2)
    q = generate_prime(bits // 2)
    
    # 计算模数
    n = p * q
    phi = (p - 1) * (q - 1)
    
    # 公钥指数(常用65537)
    e = 65537
    # 确保互素
    while gcd(e, phi) != 1:
        e = random.randrange(3, phi, 2)
    
    # 私钥指数(扩展欧几里得算法)
    d = pow(e, -1, phi)
    
    return (n, e), (n, d)

def rsa_encrypt(m, pub_key):
    """RSA加密"""
    n, e = pub_key
    return pow(m, e, n)

def rsa_decrypt(c, priv_key):
    """RSA解密"""
    n, d = priv_key
    return pow(c, d, n)

# 使用示例
pub_key, priv_key = rsa_keygen(2048)
message = 123456789  # 实际应使用填充后的消息
ciphertext = rsa_encrypt(message, pub_key)
plaintext = rsa_decrypt(ciphertext, priv_key)
print(f"原始消息: {message}")
print(f"解密结果: {plaintext}")
print(f"加解密正确: {message == plaintext}")
关键说明:上述代码中的 pow(m, e, n) 使用Python内置的模幂运算,采用平方-乘算法,时间复杂度为 O(log e) 次模乘运算。实际工程中应使用 cryptography.hazmat.primitives.asymmetric.rsa 等成熟库,并配合OAEP填充使用。