当前位置:文档之家› RSA加密算法_源代码__C语言实现

RSA加密算法_源代码__C语言实现

密钥对的产生。选择两个大素数,p和q。计算:n = p * q然后随机选择加密密钥e,要求e和( p - 1 ) * ( q - 1 )互质。最后,利用Euclid算法计算解密密钥d,满足e * d = 1 ( mod ( p - 1 ) * ( q - 1 ) )其中n和d也要互质。数e和n是公钥,d是私钥。两个素数p和q不再需要,应该丢弃,不要让任何人知道。加密信息m(二进制表示)时,首先把m分成等长数据块m1 ,m2,..., mi,块长s,其中2^s <= n, s尽可能的大。对应的密文是:ci = mi^e ( mod n ) ( a )解密时作如下计算:mi = ci^d ( mod n ) ( b )
RSA算法
1978年就出现了这种算法,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir和Leonard Adleman。但RSA的安全性一直未能得到理论上的证明。
RSA的安全性依赖于大数难于分解这一特点。公钥和私钥都是两个大素数(大于100个十进制位)的函数。据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积。
} b--; //c=a * c % n; //这里也会溢出,若把64位整数拆为两个32位整数不知是否可以解决这个问题。
c=MulMod(a, c, n);
} return c;
}/*
Rabin-Miller素数测试,通过测试返回1,否则返回0。
n是待测素数。
注意:通过测试并不一定就是素数,非素数通过测试的概率是1/4
5,
7,
11,
13,
17,
19,
23,
29,
31,
37,
41,
43,
47,
53,
59,
61,
67,
71,
73,
79,
83,
89,
97
};
const static long g_PrimeCount=sizeof(g_PrimeTable) / sizeof(long);const unsigned __int64 multiplier=12747293821;
typedef struct RSA_PARAM_Tag
{
unsigned __int64 p, q; //两个素数,不参与加密解密运算
unsigned __int64 f; //f=(p-1)*(q-1),不参与加密解密运算
unsigned __int64 n, e; //公匙,n=p*q,gcd(e,f)=1
const unsigned __int64 adder=1343545677842234541;//随机数类
class RandNumber
{
/* */
private:
unsigned __int64 randSeed;/* */
public:
RandNumber(unsigned __int64 s=0);
*/
long RabinMillerKnl(unsigned __int64 &n)
{
unsigned __int64 b, m, j, v, i;
unsigned __int64 Random(unsigned __int64 n);
};/* */
RandNumber::RandNumber(unsigned __int64 s)
{
if(!s)
{
randSeed= (unsigned __int64)time(NULL);
}
else
{
randSeed=s;
unsigned __int64 d; //私匙,e*d=1 (mod f),gcd(n,d)=1
unsigned __int64 s; //块长,满足2^s<=n的最大的s,即log2(n)
} RSA_PARAM;//小素数表
const static long g_PrimeTable[]=
{
3,
由于进行的都是大数计算,使得RSA最快的情况也比DES慢上100倍,无论是软件还是硬件实现。速度一直是RSA的缺陷。一般来说只用于少量数据加密。
*/
#include <iostream>
#include <stdlib>
#include <time>using namespace std;//RSA算法所需参数
RSA可用于数字签名,方案是用( a )式签名,( b )式验证。具体操作时考虑到安全性和m信息量较大等因素,一般是先作HASH运算。RSA的安全性。RSA的安全性依赖于大数分解,但是否等同于大数分解一直未能得到理论上的证明,因为没有证明破解RSA就一定需要作大数分解。假设存在一种无须分解大数的算法,那它肯定可以修改成为大数分解算法。目前,RSA的一些变种算法已被证明等价于大数分解。不管怎样,分解n是最显然的攻击方法。现在,人们已能分解140多个十进制位的大素数。因此,模数n必须选大一些,因具体适用情况而定。
{
unsigned __int64 a=base, b=pow, c=1;
while(b)
{
while(!(b & 1))
{
b>>=1; //a=a * a % n; //函数看起来可以处理64位的整数,但由于这里a*a在a>=2^32时已经造成了溢出,因此实际处理范围没有64位
a=MulMod(a, a, n);
*/
inline unsigned __int64 MulMod(unsigned __int64 a, unsigned __int64 b, unsigned __int6;
}/*
模幂运算,返回值x=base^pow mod n
*/
unsigned __int64 PowMod(unsigned __int64 &base, unsigned __int64 &pow, unsigned __int64 &n)
}
}/* */
unsigned __int64 RandNumber::Random(unsigned __int64 n)
{
randSeed=multiplier * randSeed + adder;
return randSeed % n;
}static RandNumber g_Rnd;/*
模乘运算,返回值x=a*b mod n
相关主题