RSA是一套用了多年的加密系统,主要运用了数论中大数难以分解但是一个大的素数又相对比较容易判断的性质,关键理论可以查询 欧拉定理、大数运算、素数判定、快速指数模运算,扩展欧几里得算法。

代码如下:采用long long 类型使用小素数进行算法演示,未进行分段处理,所以单个字符加密结果一样。

  1. /*  
  2. 此程序用于演示RSA加密原理  
  3. winxos 2010-3-25*/ 
  4. #include <iostream>    
  5. #include <cmath>  
  6. #include <ctime>  
  7. #include <string>  
  8. #include <vector>  
  9. #include <iomanip>  
  10. using namespace std;     
  11. typedef long long BIG;  
  12. /*欧几里得扩展算法,计算乘法逆元*/ 
  13. BIG gcdx(BIG a,BIG b,BIG &x,BIG &y)  
  14. {  
  15.     if (a == 1)  
  16.     {  
  17.         x = 1;  
  18.         y = 0;  
  19.         return a;   
  20.     }  
  21.     BIG r = gcdx(b,a%b,x,y);  
  22.     BIG t = x;  
  23.     x = y;  
  24.     y = t - a / b * y;  
  25.     return r;  
  26. }  
  27. /*快速指数模运算*/ 
  28. BIG powmod(BIG a,BIG b,BIG n)  
  29. {  
  30.     if (b <= 0) return 1;  
  31.     if (b == 1) return a % n;  
  32.     BIG temp = powmod(a,b/2,n);  
  33.     temp = temp * temp % n;  
  34.     if (b % 2 == 1) //如果奇数要多乘一次  
  35.     {  
  36.         temp = temp * a % n;  
  37.     }  
  38.     return temp;  
  39. }  
  40. /*简易素数判定*/ 
  41. bool isprime(BIG n)  
  42. {  
  43.     if (n == 2 || n == 3 || n == 5)   
  44.         return true;  
  45.     if (n < 2 || n % 2 == 0 ||   
  46.         n % 3 == 0 || n % 5 == 0)   
  47.         return false;  
  48.     for (BIG i = 5;i <= sqrt(static_cast<double>(n));i += 6)  
  49.     {  
  50.         if (n % i == 0 || n % (i+2) == 0)  
  51.         {  
  52.             return false;  
  53.         }  
  54.     }  
  55.     return true;  
  56. }  
  57. /*得到下一个素数*/ 
  58. BIG nextprime(BIG n)  
  59. {  
  60.     BIG t = n;  
  61.     while (!isprime(++t));  
  62.     return t;  
  63. }  
  64. //RSA加密算法演示,采用BIG类型演示原理,当然实际要采用上数百位的素数合成n  
  65. /*本函数用于加密一个基本元数据*/ 
  66. BIG unitRSAencrypt(BIG source_data_unit,BIG encrypt_key, BIG n_modkey)  
  67. {  
  68.     return powmod(source_data_unit,encrypt_key,n_modkey);  
  69. }  
  70. /*本函数用于解密一个基本元数据*/ 
  71. BIG unitRSAdecrypt(BIG encrypted_data_unit,BIG decrypt_key, BIG n_modkey)  
  72. {  
  73.     return powmod(encrypted_data_unit,decrypt_key,n_modkey);  
  74. }  
  75. /*  
  76. 密钥生成参数选择:来自维基百科http://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95  
  77. 素数p和q还要满足一定的要求,首先它们不能太靠近,此外p-1或q-1的因子不能太小,否则的话N也可以被很快地分解。  
  78. 此外寻找質|数的算法不能给***者任何信息,这些質|数是怎样找到的,尤其产生随机数的软件必须非常好。要求是随机和不可预测。这两个要求并不相同。一个随机过程可能可以产生一个不相关的数的系列,但假如有人能够预测出(或部分地预测出)这个系列的话,那么它就已经不可靠了。比如有一些非常好的随机数算法,但它们都已经被发表,因此它们不能被使用,因为假如一个***者可以猜出p和q一半的位的话,那么他们就已经可以轻而易举地推算出另一半。此外密钥d必须足够大,年有人证明假如p大于q而小于q(这是一个很经常的情况)而d < N1/4/3,那么从N and e可以很有效地推算出d。此外e = 2永远不应该被使用。*/ 
  79.  
  80. /*密钥创建函数,生成e, d, n*/ 
  81. void create_random_keys(BIG &encrypt_key,BIG &decrypt_key,BIG &n_modkeky)  
  82. {  
  83.     srand(static_cast<unsigned int>(time(NULL)));  
  84.     BIG seed,p1,p2,phi,temp;  
  85.     seed = rand() % 10000 + 10000; // the range of the first prime  
  86.     p1 = nextprime(seed); // create the first prime.  
  87.     seed += rand() % 10000 + 10000; //  
  88.     p2 = nextprime(seed); // create the second prime, bigger than the first one.  
  89.     n_modkeky = p1 * p2; // set the n_modkey  
  90.     phi = (p1 - 1) * (p2 - 1); // calculator the function phi(n).  
  91.     do   
  92.     {  
  93.         seed = rand() % 100 + 3;  
  94.         encrypt_key = nextprime(seed); // create encrypt key, do not need very big  
  95.     } while (gcdx(encrypt_key,phi,seed,temp) != 1);  
  96.     gcdx(encrypt_key,phi,decrypt_key,temp); // get the decrypt key  
  97.     if (decrypt_key < 0) //if decrypt_key is blow zero, need to convert it to the positive filed.  
  98.     {  
  99.         decrypt_key += phi;  
  100.     }  
  101. }  
  102. void print(vector<BIG> data)  
  103. {  
  104.     for (size_t i = 0;i < data.size();i++)  
  105.     {  
  106.         cout<<setw(20)<<data[i];  
  107.     }  
  108.     cout<<endl;  
  109. }  
  110. vector<BIG> predeal_string(string msg)  
  111. {  
  112.     return vector<BIG> (msg.begin(),msg.end());  
  113. }  
  114. string recover_string(vector<BIG> c_msg)  
  115. {  
  116.     string str_ret = "";  
  117.     for (size_t si = 0;si < c_msg.size();si++)  
  118.     {  
  119.         str_ret += static_cast<char> (c_msg[si]);  
  120.     }  
  121.     return str_ret;  
  122. }  
  123. vector<BIG> RSAengypt(string s,BIG e,BIG n)  
  124. {  
  125.     vector<BIG> s_ret = predeal_string(s);  
  126.     for (size_t i = 0;i < s_ret.size();i++)  
  127.     {  
  128.         s_ret[i] = unitRSAencrypt(s_ret[i],e,n);  
  129.     }  
  130.     return s_ret;  
  131. }  
  132. string RSAdegypt(vector<BIG> s,BIG d,BIG n)  
  133. {  
  134.     for (size_t i = 0;i < s.size();i++)  
  135.     {  
  136.         s[i] = unitRSAencrypt(s[i],d,n);  
  137.     }  
  138.     string str_ret = recover_string(s);  
  139.     return str_ret;  
  140. }  
  141.  
  142. int main()     
  143. {     
  144.     BIG e,d,n;  
  145.     string s = "hello world! how are you been these days? ~!@#$%^&*()_+|`1234567890-=;',./";  
  146.     cout<<"原始密文:\n"<<s<<endl;  
  147.     create_random_keys(e,d,n);  
  148.     cout<<"公钥:"<<e<<", "<<n<<" 密钥:"<<d<<", "<<n<<endl;  
  149.     vector<BIG> t = RSAengypt(s,e,n);  
  150.     cout<<"加密后数据内容:"<<endl;  
  151.     print(t);  
  152.     string s2 = RSAdegypt(t,d,n);  
  153.     cout<<"解密密文:\n"<<s2<<endl;  
  154.     return 0;     
  155. }    
  156.    
  157.  

-----------运行结果--------------------

原始密文:
hello world! how are you been these days? ~!@#$%^&*()_+|`1234567890-=;',./
公钥:89, 481406479 密钥:275835689, 481406479
加密后数据内容:
            26043171           327399490           230621758           230621758
           231959055           260178933           414628633           231959055
           164067963           230621758           205590903           203384337
           260178933            26043171           231959055           414628633
           260178933            80201433           164067963           327399490
           260178933           140426015           231959055           407828208
           260178933            19332027           327399490           327399490
           481256803           260178933           239604623            26043171
           327399490           139578934           327399490           260178933
           205590903            80201433           140426015           139578934
           313413852           260178933            99061361           203384337
           207195739           109971008           274464649           162447453
           140289974           449722463           404921537            55375979
           467769239           244872881            23021321           378874344
            23104759           189537375           231354613           435450394
           478134577            65343791           416929531           258498836
           359182479            14267219            98398916           262255901
           144277209            64215557            32213092           114061293
             7902659           109199965
解密密文:
hello world! how are you been these days? ~!@#$%^&*()_+|`1234567890-=;',./
请按任意键继续. . .

2010-3-25