简介: 本文详细解析了RSA无填充加密的原理,并提供完整的Python实现代码。通过分步讲解密钥生成、加密解密过程,结合数学推导与实际案例,帮助开发者深入理解RSA算法核心机制,适用于小数据量安全传输场景。
RSA作为非对称加密的基石算法,其无填充实现是理解公钥密码学的关键入口。本文将通过数学原理推导、Python代码实现和安全实践三个维度,完整呈现RSA无填充加密的技术全貌。
RSA的安全性建立在数论难题之上,核心是欧拉定理:若a与n互质,则a^φ(n) ≡ 1 mod n,其中φ(n)是欧拉函数。对于质数乘积n=pq,φ(n)=(p-1)(q-1)。模反元素e满足e*d ≡ 1 mod φ(n),其中e是公钥指数,d是私钥指数。
加密:c = m^e mod n
解密:m = c^d mod n
无填充模式下,明文m必须满足0 < m < n,否则会导致解密失败。这种限制要求我们严格处理输入数据长度。
import randomimport mathdef is_prime(num):if num < 2:return Falsefor i in range(2, int(math.sqrt(num)) + 1):if num % i == 0:return Falsereturn Truedef generate_prime(bits):while True:num = random.getrandbits(bits)if num % 2 == 0:num += 1if is_prime(num):return numdef extended_gcd(a, b):if a == 0:return (b, 0, 1)else:g, y, x = extended_gcd(b % a, a)return (g, x - (b // a) * y, y)def modinv(a, m):g, x, y = extended_gcd(a, m)if g != 1:raise Exception('Modular inverse does not exist')else:return x % mdef generate_keys(bits=16):p = generate_prime(bits // 2)q = generate_prime(bits // 2)while p == q:q = generate_prime(bits // 2)n = p * qphi = (p - 1) * (q - 1)e = 65537 # 常用公钥指数while math.gcd(e, phi) != 1:e += 2d = modinv(e, phi)return ((e, n), (d, n))
def rsa_encrypt(m, public_key):e, n = public_keyif m >= n:raise ValueError("Message too large for modulus")return pow(m, e, n)def rsa_decrypt(c, private_key):d, n = private_keyreturn pow(c, d, n)
原始实现使用试除法,对于1024位密钥效率低下。实际应采用:
扩展欧几里得算法是计算模逆的核心。注意处理gcd(e,φ(n))≠1的情况,此时需要重新选择e值。标准实现中e=65537是安全且高效的选择。
无填充RSA要求明文m < n。实现时应添加:
def validate_message(m, n):if m < 0 or m >= n:raise ValueError(f"Message must be in range [0, {n-1}]")
无填充RSA存在以下风险:
e=3且明文相同时)
# 生成16位密钥(仅用于演示,实际不安全)public_key, private_key = generate_keys(16)print(f"Public Key (e,n): {public_key}")print(f"Private Key (d,n): {private_key}")# 加密示例message = 123 # 必须满足 0 < message < ntry:validate_message(message, public_key[1])ciphertext = rsa_encrypt(message, public_key)print(f"Ciphertext: {ciphertext}")decrypted = rsa_decrypt(ciphertext, private_key)print(f"Decrypted: {decrypted}")except ValueError as e:print(f"Error: {e}")
p和q分别解密后合并结果Q:为什么无填充RSA不安全?
A:缺乏填充导致明文结构直接暴露,易受多种攻击。如两个相同明文用相同e加密时,c1^e ≡ c2^e mod n可推导出明文关系。
Q:如何选择合适的e值?
A:常用65537(0x10001),因其:
Q:为什么密钥长度重要?
A:密钥长度决定安全强度。1024位密钥已不安全,推荐:
本文提供的实现完整展示了RSA无填充加密的核心机制,但强调在实际应用中必须结合安全填充方案。开发者可通过调整generate_keys()中的位数参数生成不同强度的密钥,但需注意小位数密钥仅适用于教学演示。