对RSA算法有些简单的看法,作为总结,也希望能为初学者提供一点参考。
1. 公钥和私钥
公钥由两部分组成: (e, n)
私钥也有两部分组成:(d, n)
e: 公有指数,是一个比较小的素数,比如:3, 7, 11,65537
d: 私有指数,是一个大素数,位数与n一致,如1024位或2048bit
n: 模,也叫合数,是一个大整数,它的位数就是RSA密钥的强度,如1024bit或2048bit
关于私钥,在PKCS#1规范中定义了另一种形式:CRT格式
CRT格式的私钥包含了很多个元素,如 (n,p,q,e,dp,dq)
对于CRT格式的私钥本人并未深入研究,在此仅介绍CRT格式私钥存在的原因: 为了优化私钥计算的速度而存在。
2. RSA计算原理
RSA的公钥和私钥核心算法是完全一致的,差别仅是参与计算的元素不同。
核心公式: c = m^exp%n
其中:
c 表述密文
m 表示原文
n 表示模(即合数)
^ 表示幂运算
exp 是幂运算的指数
% 是模运算(也就是取余运算)
这个公式也被写成: c = m^exp mod n
其中mod就是模运算。
对于公钥计算: exp就是公钥中的e值。
对于私钥计算: exp就是私钥中的d值。
上面这个公式所也被称为幂模运算。
可以看到,由于e远远小于d,以RSA-1024为例,e最大通常就取65537,而d则是一个1024bit长度的整数。
公钥计算时,将原文进行的时65537次方运算,而私钥计算时次方数则相比之下非常巨大。
所以:RSA私钥运算的运算量远远大于公钥运算。
而CRT形式的私钥,则可以利用中国剩余定理(CRT)进行很大程度的计算优化,从而加速私钥计算。
3. 加密与签名
加密与签名是RSA算法的两种使用场景,其核心算法都一样(幂模运算)。
对于加密
典型的应用场景:密钥交换,我们使用对方的公钥将秘密信息加密后,把密文发送给对方。在没有私钥的情况下,攻击者将没有办法解密处秘密信息。对方使用自己持有的私钥则可以解密出秘密信息。这里的秘密信息通常是一个对称密钥。
RSA(公钥,明文) = 密文
RSA(私钥,密文) = 明文
对于验签
典型的应用场景:数字证书,我们写的一个文件(如邮件、视频、MP3、PDF等),为了防止被别人篡改后冒充正版拿去骗人,我们会将源文件计算一个特征值(HASH),然后使用我们持有的私钥将特征值加密后与源文件合并后一同发送给接收人。接收人通过其他公开渠道(如邮件、网站等)拿到我的公钥,然后使用这个公钥就能验证他收到的文件是不是原版的了。
签名过程:
HASH = HASH算法(明文)
签名数据 = RSA(私钥, HASH)
传输数据 = 明文+签名
验签过程:
HASH1 = HASH算法(明文)
HASH2 = RSA(公钥, 签名数据)
HASH1 == HASH2则验签通过。
4. RSA密钥的产生
以上内容仅涉及RSA的密钥使用,不涉及RSA的密钥产生。
RSA的密钥产生则需要对RSA算法进行深入了解,这里仅介绍皮毛。
公钥和私钥中的元素: e是约定的比如65537,d和n则是算出来的。
d和n是通过两个大素数p,q来算出来的,怎么算的这里忽略。
RSA密钥的产生,核心就是要产生两个大素数,因此可以简单理解为,RSA密钥是这样产生的:
a. 产生随机数X (随机数算法)
b. 检查X是否素数 (素数判别算法),如果不是则重做a
c. 产生随机数Y
d. 检查Y是否随机数,如果不是则重做c
e. 将X,Y作为p,q,并加入e(如65537),计算得到n和d