Rivest-Shamir-Adleman (RSA),RSA 算法以它的创造者罗纳德·李维斯特、阿迪·沙米尔和伦纳德·阿德曼的名字命名,他们于 1977 年首次披露了这一算法,被视为最具影响力的加密方法之一。
这种基于公钥加密的加密技术构成了互联网上数据安全传输的基础。RSA 算法不仅改变了安全通信的实施方式,还为数字安全领域的多项突破奠定了基础。
RSA 算法依赖于大质数因式分解的数学难题。RSA 的安全性在于找出生成给定大合数的两个大质数这一难题,有时也称为质因数分解。随着数字规模的增大,这个问题的计算复杂度呈指数级增长,这确保了 RSA 算法的安全性。
–
密钥生成
RSA 算法始于密钥的生成。该过程包含以下几个步骤:
- 素数和模数的选择。随机选取两个大素数 p 和 q。这两个数的乘积 n = p × q 用作公钥和私钥的模数。n 的值必须足够大以确保安全性,通常有数百位之长。
- 欧拉函数的计算。欧拉函数 φ(n) 的计算公式为 φ(n) = (p - 1) × (q - 1)。此值对于确定公钥和私钥至关重要。
- 公钥生成。公钥由模数 n 和公指数 e 组成,e 通常是像 3 或 65537 这样的小质数,选择时要确保其与 φ(n) 互质。
- 私钥生成。私钥是从相同的模数生成的。请提供需要翻译的原文。n 以及一个私钥指数 d,它是 ee 模 φ(n) 的模反元素。
加密与解密涉及模运算:
- 加密。发送方将明文消息转换为数字格式(明文整数 m)。然后使用以下公式生成密文 c:c = m^e mod n 。
- 解密。接收方使用私钥和公式 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 的安全基础。