RSA 加密算法是一种基于大素数分解的非对称加密算法,广泛应用于安全通信领域。然而,在某些情况下,如果 RSA 模数 ( n ) 小于要加密的消息,可能会导致消息在解密时无法被完全还原。本文将详细探讨这种现象的成因,如何生成 RSA 密钥,以及通过一个具体例子展示如何加密和解密消息。
先看结论
最近在学习rsa时突突发奇想想要手算一下,为了手算方便值就取得很小,导致计算出的n值很小(15),这时候加密的消息必须小于15,否则加密后解密不出明文(白话剖析请看问题分析部分)
原因:
在 RSA 加密中,模数 ( n ) 的大小至关重要。如果模数 ( n ) 小于消息,则会导致加密后的消息无法正确还原。所以为了避免这种情况,模数 ( n ) 必须大于消息 ( M ),并且在实际应用中,建议使用 1024 位以上的模数,以确保安全性和完整性。
什么是 RSA 加密?
RSA 是一种非对称加密算法,它使用两个密钥:公钥 ( (e, n) ) 和私钥 ( (d, n) )。公钥用于加密消息,私钥用于解密。加密和解密的公式如下:
-
加密: ( C = M^e \mod n )
- 其中 ( M ) 是消息,( C ) 是密文,( e ) 是公钥指数,( n ) 是模数。
-
解密: ( M = C^d \mod n )
- 其中 ( d ) 是私钥指数。
为什么模数 ( n ) 小于消息会导致还原失败?
RSA 的加密过程涉及模运算。如果消息 ( M ) 大于模数 ( n ),那么在加密时,消息会被取模 ( n ) 后进行运算,导致原始消息的部分信息丢失。
例如,假设模数 ( n = 15 ),要加密的消息 ( M = 25 )。在加密过程中会进行 ( M \mod n ) 运算,结果为:
[ 25 \mod 15 = 10 ]
这意味着实际加密的消息变成了 10,导致在解密时恢复的不是原始的 25,而是 10。为了避免这种问题,必须确保 模数 ( n ) 大于要加密的消息 ( M )。
RSA 密钥生成步骤
为了生成 RSA 的公钥和私钥,通常需要以下步骤:
1. 选择两个大素数 ( p ) 和 ( q ):
选择两个足够大的素数 ( p ) 和 ( q ),这些素数越大,RSA 的加密强度就越高。
2. 计算模数 ( n ):
计算 n = p × q ,该值作为公钥和私钥的一部分。模数 ( n ) 的大小直接决定了 RSA 系统的加密能力。
3. 计算欧拉函数 ( φ(n) ):
计算 φ(n) = (p - 1) × (q - 1) ),欧拉函数用于后续选择加密指数。
4. 选择加密指数 ( e ):
选择一个与 ( φ(n) ) 互质的整数 ( e )(通常选用65537)。这个 ( e ) 将作为公钥的一部分。
5. 计算私钥指数 ( d ):
私钥指数 ( d ) 满足以下条件:
d
×
e
≡
1
(
mod
φ
(
n
)
)
d \times e \equiv 1 \ (\text{mod} \ φ(n))
d×e≡1 (mod φ(n))
即 ( d ) 是 ( e ) 关于模 ( φ(n) ) 的逆元。
6. 生成公钥和私钥:
- 公钥:( e, n )
- 私钥:( d, n )
手算惨案重现
为了方便手算,p,q取值如下
- ( p = 3 )
- ( q = 5 )
1. 计算模数 ( n ):
n = p × q = 3 × 5 = 15 n = p \times q = 3 \times 5 = 15 n=p×q=3×5=15
2. 计算欧拉函数 ( φ(n) ):
φ ( n ) = ( p − 1 ) × ( q − 1 ) = 2 × 4 = 8 φ(n) = (p - 1) \times (q - 1) = 2 \times 4 = 8 φ(n)=(p−1)×(q−1)=2×4=8
3. 选择加密指数 ( e = 7 ):
验证 ( e = 7 ) 与 ( φ(n) = 8 ) 互质,gcd(7, 8) = 1 ,因此 ( e ) 合法。
4. 计算私钥指数 ( d ):
d × e ≡ 1 ( mod φ ( n ) ) d \times e \equiv 1 \ (\text{mod} \ φ(n)) d×e≡1 (mod φ(n))
。经过计算,( d = 7 ) 满足该条件。
5. 公钥和私钥:
- 公钥:( 7, 15 )
- 私钥:( 7, 15 )
案发现场
加密步骤
开始加密的消息是 ( M = 25 )。加密公式为:
C
=
M
e
m
o
d
n
C = M^e \mod n
C=Memodn
即:
C
=
2
5
7
m
o
d
15
C = 25^7 \mod 15
C=257mod15
手算结果:
加密后的密文 ( C = 10 )。
解密步骤
现在使用私钥 ( (d, n) = (7, 15) ) 对密文 ( C = 10 ) 进行解密。解密公式为:
M
=
C
d
m
o
d
n
M = C^d \mod n
M=Cdmodn
即:
M
=
1
0
7
m
o
d
15
M = 10^7 \mod 15
M=107mod15
简单计算:
M计算出来他居然是10,这可怎么办啊???😅😅😅
这时候我就蒙了啊,我怀疑过密钥对算错了,怀疑过质数取错了,后来仔细研究了一下公式才发现,原来是n太小了(原因就是我数学过于差劲,太丢人了🙄),解释如下:
问题分析:
加密解密过程未能还原消息 ( M = 25 ),因为模数 ( n = 15 ) 太小,导致消息经过模运算被截断。因此我们得到了 ( 25 \mod 15 = 10 ),加密的实际是消息 10,而不是 25。
说人话,因为在你解密的时候最后要取模,取模是什么啊,取模结果一定是小于模数的,模数15,那么解密只能解出比15小的明文。
总结
在 RSA 加密中,模数 ( n ) 的大小至关重要。如果模数 ( n ) 小于消息,则会导致加密后的消息无法正确还原。为了避免这种情况,模数 ( n ) 必须大于消息 ( M ),并且在实际应用中,建议使用 1024 位以上的模数,以确保安全性和完整性。
题外话
正因为不能解密大于等于n的消息,所以在加密日常消息的时候一定是要进行切分,然后加密消息块,这样做效率太低。因此RSA 通常用于加密对称加密的密钥,而不是直接加密较长的消息。对于长消息,常见的做法是使用 对称加密(如 AES)对消息进行加密,再用 RSA 加密对称密钥。
(有人可能会说n取的足够大就好了啊,又不是人算,那加密一篇很长的文章是不是要取个巨大的n,如果能达到解密加密不影响用户体验时间设备可能成本也不小,说不定那时候的算力已经可以很快破解分解大质数的能力,那么这种加密也就无用了)