一文搞懂 RSA 算法
RSA 是地球上最重要的算法,没有之一。
如果没有 RSA 算法,现在的网络世界毫无安全可言,也不可能有现在的网上交易。众所周知的 ssh 协议也是基于 RSA 加密算法才能确保通讯是加密的,可靠的。
1976年以前,所有的加密方法都使用对称加密算法:加密和解密使用同一套规则。例如:甲使用密钥 A 加密,将密文传递给乙,乙仍使用密钥 A 解密。如果密钥 A 在甲传递给乙的过程中泄露,或者根据已知的几次密文和明文推导出密钥 A,则甲乙之间的通讯将毫无秘密。
1976年,两位美国计算机学家 Whitfield Diffie 和 Martin Hellman,提出了一种崭新构思,可以在不传递密钥的情况下,完成解密。这被称为 Diffie-Hellman密钥交换算法 假如甲要和乙通讯,甲使用公钥 A 加密,将密文传递给乙,乙使用私钥 B 解密得到明文。其中公钥在网络上传递,私钥只有乙自己拥有,不在网络上传递,这样即使知道了公钥 A 也无法解密。反过来通讯也一样。只要私钥不泄漏,通信就是安全的,这就是非对称加密算法。
1977年,三位数学家 Rivest、Shamir 和 Adleman (见上图)设计了一种算法,可以实现非对称加密。算法用他们三个人的名字命名,叫做 RSA 算法。直到现在,RSA 算法仍是最广泛使用的"非对称加密算法"。毫不夸张地说,只要有计算机网络的地方,就有 RSA 算法。
只是以上描述并不能让你感受到 RSA 的魅力,我举一个简单的例子。
甲向乙发消息,要确保只有乙可以看懂,那么需要乙拥有一对密钥,既公钥和私钥。假设乙已经有了公钥(n,e) = (4757 , 101) 和私钥(n,d) = (4757 ,1601), 公钥可以在网络上传输,泄露也没关系,私钥只有乙自己知道,不传输。
加密过程
甲要向乙发送信息“中”,就要使用乙的公钥加密汉字 "中",计算机只处理数据,汉字“中”通过 utf-8 编码为 [e4 b8 ad],转为 10 进制为 [228,184,173]。要想使用公钥(n,e) = (4757 , 101) 加密,要求被加密的数字必须小于 n,被加密的数字必须是整数,字符串可以取 ascii 值或 unicode 值,因此将“中”字折为三个字节 [228,184,173],分别对三个字节加密。 假设 a 为明文,b 为密文,则按下列公式计算出 b
计算 [228,184,173] 的密文如下:
即汉字“中”([228,184,173])加密后得到密文 [4296,2458,3263],如果没有私钥,神仙也无法从 [4296,2458,3263] 中解密出 [228,184,173]。
解密过程
乙收到密文 [4296,2458,3263],并用自己的私钥(n,d) = (4757 ,1601) 解密。解密公式如下: 假设 a 为明文,b 为密文,则按下列公式计算出 a
密文 [4296,2458,3263]的明文如下:
即密文 [4296,2458,3263] 解密后得到 [228,184,173] 将[228,184,173] 再按 utf-8 解码为汉字 "中",至此解密完毕。
密钥对的生成过程
你可能想知道,公钥(n,e) = (4757 , 101) 和私钥(n,d) = (4757 ,1601) 是怎么生成的,且看下面的步骤。
1、随机找两个质数 P 和 Q ,P 与 Q 越大,越安全。
比如 P = 67 ,Q = 71。计算他们的乘积 n = P * Q = 4757 ,转化为二进为 1001010010101,该加密算法即为 13 位,实际使用中的算法是往往是 1024 位 或 2048 位,位数越长,算法越难被破解。
2、计算 n 的欧拉函数 φ(n)。
φ(n) 表示在小于等于 n 的正整数之中,与 n 构成互质关系的数的个数。例如:在 1 到 8 之中,与 8 形成互质关系的是 1、3、5、7,所以 φ(n) = 4。 如果 n = P * Q,P 与 Q 均为质数,则
本例中 φ(n) = 66 * 70 = 4620,这里记为 m, m = φ(n) = 4620
3、随机选择一个整数 e,条件是 1< e < m,且 e 与 m 互质。
公约数只有 1 的两个整数,叫做互质整数,这里我们随机选择 e = 101 请注意不要选择 4619,如果选这个,则公钥和私钥将变得相同。
4、找到一个整数 d,可以使得 e*d 除以 m 的余数为 1。
即找一个整数 d,使得 (e d ) % m = 1。 等价于 e d - 1 = y * m ( y 为整数) 找到 d ,实质就是对下面二元一次方程求解:
其中 e = 101,m = 4620,既 101x - 4620y =1,解这个方程可以用"扩展欧几里得算法"求解,此处省略具体过程。 总之算出一组整数解
即 d = 1601。 到此密钥对生成完毕。不同的 e 生成不同的 d,因此可以生成多个密钥对。
本例中公钥为 (n,e) = (4757,101),私钥为 (n,d) = (4757,1601),仅(n,e) = (4757,101) 是公开的,其余数字均不公开。可以想像如果只有 n 和 e,如何推导出 d,目前只能靠暴力破解,位数越长,暴力破解的时间越长。
其他细节
加密和解密的过程使用了费尔马小定理的两种等价的描述。
有人会问,有没有可能在已知 (n,e) 的情况下,推导出 d。
根据以上密钥对的生成过程:
如果想知道 d 需要知道欧拉函数 φ(n)
如果想知道欧拉函数 φ(n) 需要知道 P 和 Q
要知道 P 和 Q 需要对 n 进行因数分解。
对于本例中的 4757 你可以轻松进行因数分解,但对于大整数的因数分解,是一件很困难的事情,目前除了暴力破解,还没有更好的办法,如果以目前的计算速度,破解需要50年以上,则这个算法就是安全的。 维基百科这样描述:
>对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法,那么RSA的可靠性就会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA密钥才可能被暴力破解。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要密钥长度足够长,用RSA加密的信息实际上是不能被解破的。"
目前已经破解的最大整数:
即 232 个十进制位,768 个二进制位,目前被破解的最长 RSA 密钥就是 768 位。实际应用中 RSA 的密钥长度为 1024 位,重要场合 2048 位,未来半个世纪不可能破解。
参考文档:
RSA算法原理(二)(阮一峰)(http://www.ruanyifeng.com/blog/2013/07/rsaalgorithmpart_two.html)
数学之美:谈谈密码学的数学原理(吴军)
如果您对文章感兴趣,请微信搜索「Python七号」并关注。
版权声明: 本文为 InfoQ 作者【somenzz】的原创文章。
原文链接:【http://xie.infoq.cn/article/9985c080b97368e8cd73dad47】。文章转载请联系作者。
评论