本篇文章总结了我对RSA算法的理解和设计,并在后文对优化运行效率的方法做了对比分析。
一、RSA算法简介
密码学是研究如何隐密地传递信息的学科,它被认为是数学和计算机科学的分支,和信息论也密切相关。在很久之前的传统密码学中,使用的都是对称加密算法,即使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密。而现在使用的多为非对称加密算法。
RSA算法是一种著名的非对称加密算法,所谓非对称加密就是说用来加密的密钥和用来解密的密钥是不同的。用来加密的为公钥,是公共的数据,而负责解密的为私钥,是不公开的。利用这种信息不对称的手段,使得该类算法安全性很高,非对称加密算法的大致流程如图1-1。
图1-1非对称加密
其中的公钥和私钥其实就是一组数字,其二进制位长度可以是1024位或者2048位,长度越长其加密强度越大,因为破解时的计算量会随密钥长度指数级的上升。而作为一种非对称加密算法,RSA是目前最有影响力和最常用的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法的总体流程如图1-2所示。
图1-2 RSA算法流程
RSA之所以难以被破解的主要原理为:计算两个大素数相乘是容易的,但将计算的结果逆向分解为两个素数是困难的。所以,素数的产生和计算是RSA算法中的一个重要环节。对于为什么破解RSA需要将分解因子,我在后文中进行阐述。
二、RSA算法的实现
1.产生私钥和公钥
在RSA算法的实现过程中,总体可以分为两大部分,就是产生公钥、私钥和加密解密。我对RSA产生共钥、私钥的流程总结为图2-1。
图2-1 RSA产生密钥流程
由图2-1可以发现,若想求得私钥中的d,在已知e和n的情况下,需要求得n的欧拉函数值φ(n),则就需要求得p和q。上文已经说过,在已知结果的情况下,逆向求得两个大素数p和q是非常困难的,这就是RSA可靠的原因。
后面对图2-1具体每一步的详细实现进行阐述。
(1)找到两个较大的素数和乘积n
找到两个大素数是整个RSA算法中最慢的步骤之一,这里先采用的方法是不断的生成随机数,直到找到符合要求的素数为止。
首先,需要能够判断一个数是否为素数,最简单的方法就是看这个数是否有除了1和它本身以外的其他因数,即试除法。检测素数的代码段如下。
bool IsPrime(long b)
{
for (long i = 2; i < sqrt(b); i++)
if (b%i == 0)return false;
return true;
}
能够检测素数以后,就可以进行较大素数的生成。为了达到“较大“的要求,我只对大于100的数进行筛选,实现的主要代码如下。为防止过慢,这里的GetRandom()只生成小于200的随机数。
while (1){
while (1){
p = GetRandom(); //得到随机数
if (s1 > 100 && IsPrime(s1))break; //条件为大于100的素数
}
while (1){
q = GetRandom(); //得到第二个随机数
if (s2 > 100 && IsPrime(s2))break; //条件为大于100的素数
}
if (p != q){ //两个数不能相同
cout << "p=" << p << ",q=" << q << endl;//得到两个大素数
break;
}}