RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。
RSA的算法涉及三个参数,n、e1、e2。
其中,n是两个大质数p、q的积,n的二进制表示时所占用的位数,就是所谓的密钥长度。
e1和e2是一对相关的值,e1可以任意取,但要求e1与(p-1)*(q-1)互质;再选择e2,要求(e2*e1)mod((p-1)*(q-1))=1。
(n及e1),(n及e2)就是密钥对。
RSA加解密的算法完全相同,设A为明文,B为密文,则:A=B^e1 mod n;B=A^e2 mod n;
e1和e2可以互换使用,即: A=B^e2 mod n;B=A^e1 mod n;
破解的途径是能够n逆向推出p,q两个质数,而对于商业上实用的n一般在1024bit以上,遍历自然数找到p或q是非常困难,p和q仅在生产公钥和私钥对时有用,生成完毕即丢弃,公私钥直接不能直接简单运算得出。光有公钥或者私钥都无法知道对方的,实现了非对称加密的需求,在电子商务上起着举足轻重的作用。
较新的非对称加密是称为椭圆加密(ECC)算法,其数学原理一直未能参透,直观的理解就是在离散的椭圆曲线上每个点和另外一个点是对应关系,这两个就是公钥和私钥。
最常见的算法莫过于RSA了,例子如下:以下代码选自网络,看得出只是原理性的代码,还无法用于实际,质数判定函数非常落后,应该使用质数定理来替代,质数足够大了,安全才有保障。
#include "stdafx.h"
#include<iostream>
#include<math.h>
using namespace std;
class RSA
{
long long int n;
long long int p;
long long int q;
long long int m;
long long int phi;
long long int e;
long long int d;
public:
void generatePandQ();
bool isPrime(long long int &);
void display();
void generateEandD();
long long int gcd(long long int , long long int );
void extEuclidean(long long int , long long int , long long int &, long long int &);
long long int encryption(long long int );
long long int decryption(long long int );
};
void RSA::display()
{
cout << "n =\t" << n << endl;
cout << "p =\t" << p <<endl;
cout << "q =\t" << q << endl;
cout << "phi =\t" << phi << endl;
cout << "e =\t" << e << endl;
cout << "d =\t" << d << endl;
}
void RSA::generatePandQ()
{
long long int start = 0, limit = 0;
// lets generate a prime number between start and limit
start = ( 1 << 12 ); //
limit = ( 1 << 15 ); //
long long int count = 0;
for(long long int i = start+1; i < limit ; i++)
{
if(isPrime(i))
{
count++;
if(count == 1)
p = i;
else
{
q = i;
break;
}
}
}
n = p * q;
phi = ( p - 1 )*( q - 1);
}
void RSA::generateEandD()
{
long long int start = phi >> 5;
long long int limit = phi;
for(; start < limit ; start++)
{
if(gcd( phi, start) == 1)
{
e = start;
break;
}
}
long long int x = 0;
long long int y = 0;
extEuclidean(phi, e, x, y);
while(y < 0)
{
y += phi;
}
d = y;
}
void RSA::extEuclidean(long long int a,long long int b, long long int &lastx, long long int &lasty)
{
if( b == 0)
{
lastx = 1;
lasty = 0;
}
else
{
long long int quotient = a / b;
long long int remainder = a % b;
long long int s = 0;
long long int t = 0;
extEuclidean(b, remainder, s, t);
lastx = t;
lasty = s - quotient * t;
}
}
long long int RSA::gcd( long long int a, long long int b)
{
long long int temp = 0;
while(b != 0)
{
temp = a;
a = b;
b = temp % b;
}
return a;
}
bool RSA::isPrime( long long int &x)
{
if(x % 2 == 0)
return false;
long long int lim = sqrt((long double) x);
for( long long int i = 3; i <= lim ; i += 2)
if( x % i == 0)
return false;
return true;
}
long long int RSA::encryption( long long int msg)
{
long long int i = e;
long long int e_msg = 1;
while(i)
{
i--;
e_msg = (e_msg * msg) % n;
}
return e_msg % n;
}
long long int RSA::decryption(long long int e_msg)
{
long long int i = d;
long long int d_msg = 1;
while(i)
{
i--;
d_msg = (d_msg * e_msg) % n;
}
return d_msg % n;
}
int main()
{
long long int message;
RSA obj;
obj.generatePandQ();
obj.generateEandD();
obj.display();
cout << "Enter the Message : ";
cin >> message;
long long int e_msg = 0;
e_msg = obj.encryption(message);
cout << "Encrypted message is = " << e_msg << endl;
long long int d_msg = 0;
d_msg = obj.decryption(e_msg);
cout << "Decrypted message is = " << d_msg << endl;
return 0;
}