通过两个rsa算法的实现代码初步认识RSA算法
本文所用程序源码:http://pan.baidu.com/s/1kUQyPJh
程序bmrsa
先看看第一个程序bmrsa.exe的流程图:
Bmrsa的demo.bat运行截图及注释:
1.产生第一个大素数p,用时3.1s
2.产生第二个大素数q(用时5s),以及一个与f(n) = (p-1) * (q - 1)互素的e
可以看到密文被公钥加密了:
加密结果在encrypted.txt中可以看到:
接着是用私钥解密的命令及其结果:
看到mykeys.txt中的以base64编码存储的私钥和公钥:
之所以是base64的结果,原因是bmrsa程序运行前的参数-mo6(对应解密时也要用参数-mi6)
m表示模式选择,o表示输出,6表示base64输出。
程序rsa,源码:
源码分析:
RSA.cpp中的testRSA()函数流程图如下:
我们知道RSA算法的关键在于产生公钥和私钥,在这个程序中产生RSA这些参数的函数是RsaGetParam()这个函数。我们重点看看这个函数,下面是这个函数的流程图:
从流程图中可以看出,函数先产生了两个大素数p,q,之后根据欧几里得公式算出f = (p - 1)*(q - 1)作为私钥,之后产生一个大随机数e,用SteinGcd算法判定e和f是否互素,若不互素则重新产生一个随机数再重复判断;若是互素的,则下来用Euclid算法计算d = e^(-1) mod f,得到解密密钥d,最后计算s = log2(p*q)的值作为块长(不知道这个参数有什么用)。
可以看到,程序和核心函数除了SteinGcd和Euclid算法外,关键在于大素数的生成,于是我们重点关注RandomPrime(16)这个函数调用:
函数流程也简单,就是随机产生一个16bit的大数,用RabinMiller算法判断这个数是不是素数(判断30次以让是素数的概率接近1),通过RabinMiller方法检测的大随机数就是大素数。
这个程序的运行结果:
将结果中的n放到cap4中进行大素数分解:
a).format method只用了2秒就正确分解了这个大素数
b)pollard’s rho Test Progress 方法只用了1s
3)pollard p-1 Progress 用了6秒
4)最慢的continuous fractions progress也只用了1分26秒
可以看到,对于10位的公钥n,用密码分析算法可以很快的分解出质因数,所以p和q应该大一些,RSA建议p,q都在100位10进制数以上。
问题与思考:
1.通过本实验,论述RSA算法的加密原理是什么?
答:RSA算法通过产生两个大素数p,q,用他们计算出f = (p-1)*(q-1)作为私钥,产生一个大随机数e,若e和f互素,则用e作为公钥;接下来计算p*q和e在mod f下的乘法逆元d。
公布{e,n}作为公钥,保留{p,q,f,d}作为私钥。
公钥加密时私钥解密,私钥加密时公钥解密,原理是欧拉定理的推论:M^(kf + 1)mod n = M mod n。
C是密文,M是明文,则
加密:M^e mod n = C
d=e^(-1) mod f => de = kf + 1
解密:C^d mod n = (M^e)^d mod n = M^(ed)mod n = M^(kf +1)mod n = M mod n
从而计算出明文M。
2.在上述算法中哪些模块是该算法的核心模块?
1) 产生大素数p,q的模块RandomPrime(16)
2) 判断是否素数的RM检测
3) SteinGcd用于判断e,f是否互素,Eculid用于产生逆元d
4) 大数模乘和模幂函数MulMod,PowMod,这两个函数的处理数据的能力(防止乘法溢出的能力),直接决定了产生的密钥的安全性。
3.对于一个RSA加密算法的密文,要得到明文需要哪些要素?
要解密密文,最简单的方法是有私钥d,直接解密
或者通过分解大素数n得到p,q,从而计算f,用f和e算出d,再解密