RsaA.cpp
上传用户:len888
上传日期:2015-03-06
资源大小:59k
文件大小:25k
源码类别:

CA认证

开发平台:

Visual C++

  1. // RsaA.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. //#include "RSATest1.h"
  5. #include "RsaA.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CRsaA
  13. IMPLEMENT_DYNCREATE(CRsaA, CCmdTarget)
  14. CRsaA::CRsaA()
  15. {
  16. InitInt();
  17. }
  18. CRsaA::~CRsaA()
  19. {
  20. }
  21. BEGIN_MESSAGE_MAP(CRsaA, CCmdTarget)
  22. //{{AFX_MSG_MAP(CRsaA)
  23. // NOTE - the ClassWizard will add and remove mapping macros here.
  24. //}}AFX_MSG_MAP
  25. //ON_MESSAGE(WM_COMPUTING,OnComputing)
  26. END_MESSAGE_MAP()
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CRsaA message handlers
  29. /*----------------------------------------------------------------------------
  30. 功能:进行相关大数的初始化
  31. 入口参数:无
  32. 返回值:无
  33. ----------------------------------------------------------------------------*/
  34. void CRsaA::InitInt(void)
  35. {
  36. SetZero(ZEROVALUE); //对大数变量zerovalue清零
  37. memset(mZEROVALUE,0,MLENGTH);
  38. SetZero(ONEVALUE);                      //对大数变量ONEVALUE进行清零
  39. ONEVALUE[DATALENGTH-1]=1; //ONEVALUE的最后一位为1
  40. SetZero(TWOVALUE); //将TOWVALUE进行清零
  41.     TWOVALUE[DATALENGTH-1]=2; //TOWVALUE的最后一位为2
  42. SetZero(EIGHTVALUE); //对EIGHTVALUE进行清零
  43.     EIGHTVALUE[DATALENGTH-1]=8; //最后一位为8
  44. return ;
  45. }
  46. /*---------------------------------------------------------------------------
  47. 功能:将一个大数A转换为相应的字符串形式
  48. 入口参数:大数A
  49. 返回值:相对应的字符串
  50. ----------------------------------------------------------------------------*/
  51. CString CRsaA::PrtInt(byteint A)
  52. {
  53. register i=0;
  54. int m,n;
  55. while(i<DATALENGTH && A[i]==0)          //跳过大数开始的空白0
  56. i++;
  57. if(i<DATALENGTH)
  58. m=DATALENGTH-i;                     //求出有用的大数长度
  59. n=0;
  60. //注意到这里的i已经是数组中第一个非零元素的对应位置,
  61. CString str=""; //因此下面的循环就是从数组中
  62. //存放的数的最高位开始输出。
  63. while(i<DATALENGTH)
  64. {
  65. str += (A[i++]+'0');
  66. }
  67. return str;
  68. }
  69. /*---------------------------------------------------------------------------
  70. 功能:大数A与大数B相乘,结果放入C中 A×B->C
  71. 入口参数:被乘数A和乘数B,结果C
  72. 返回值:无
  73. ----------------------------------------------------------------------------*/
  74. void CRsaA::Multiply(byteint A,byteint B,byteint C)
  75. {
  76. register i,j,w;
  77. int X,Y,Z;
  78. int Avalid=0; //Avalid=validating bits of A
  79. int Bvalid=0; //Avalid=validating bits of B
  80. while (A[Avalid]==0 && Avalid<DATALENGTH)
  81. Avalid++; //计算Avalid
  82. while (B[Bvalid]==0 && Bvalid<DATALENGTH)
  83. Bvalid++; //计算Bvalid
  84. SetZero(C); //将C清零初始化
  85. for(i=DATALENGTH-1;i>=Avalid;i--)
  86. for(j=DATALENGTH-1;j>=Bvalid;j--)       //逐位进行相乘运算
  87. {
  88. X=A[i]*B[j];        
  89. Y=X/10;
  90. Z=X-10*Y;
  91. w=i+j-(DATALENGTH-1);
  92. C[w]=C[w]+Z;
  93. C[w-1]=C[w-1]+(C[w]/10)+Y;
  94. C[w]=C[w]-(C[w]/10)*10;
  95. }
  96. return;
  97. }
  98. /*---------------------------------------------------------------------------
  99. 功能:将指定的自定义的大数进行0初始化
  100. 入口参数:大数A名
  101. 返回值:无
  102. ----------------------------------------------------------------------------*/
  103. void CRsaA::SetZero(byteint A)  
  104. {
  105. memset(A,0,DATALENGTH);                    //调用系统函数进行初始化
  106. }
  107. /*---------------------------------------------------------------------------
  108. 功能:将大数B拷贝到大数A中
  109. 入口参数:大数A,大数B
  110. 返回值:无
  111. ----------------------------------------------------------------------------*/
  112. void CRsaA::IntCpy(byteint A,byteint B)
  113. {
  114. memcpy(A,B,DATALENGTH);                    //调用系统函数完成拷贝
  115. }
  116. /*---------------------------------------------------------------------------
  117. 功能:A+B的结果送C
  118. 入口参数:大数A,B,C
  119. 返回值:无
  120. ----------------------------------------------------------------------------*/
  121. void CRsaA::Plus(byteint A,byteint B,byteint C)
  122. {
  123. register i;//,w;
  124. int X,Y,Z,m,n,valid;
  125. m=IntValid(A);                 //计算A的长度         
  126. n=IntValid(B);                 //计算B的长度
  127. valid=(m>n)?m+1:n+1;           //计算时要以最长的数为准
  128. SetZero(C);                    //将C清零
  129. for(i=DATALENGTH-1;i>=DATALENGTH-valid;i--)
  130. {
  131. X=A[i]+B[i];               //按位相加
  132. Y=X/10;
  133. Z=X-10*Y;
  134. C[i]=C[i]+Z;               //计算进位
  135. C[i-1]=C[i-1]+Y;
  136. }
  137. }
  138. /*---------------------------------------------------------------------------
  139. 功能:大数SA减去大数SB,结果放入SC
  140. 入口参数:被减数SA,减数SB,差SC
  141. 返回值:无
  142. ----------------------------------------------------------------------------*/
  143. void CRsaA::Substract(byteint SA,byteint SB,byteint SC)
  144. {
  145. byteint buf;
  146. register i,j;
  147. int X;
  148. IntCpy(buf,SA);                  //将SA的内容拷贝到buf中
  149. SetZero(SC);                 //SC清零初始化
  150. for(i=DATALENGTH-1;i>=0;i--)
  151. {
  152. if(buf[i]<SB[i])             //如果最低位不够减
  153. {
  154. buf[i]=buf[i]+10;        //向高位借1
  155. if(buf[i-1]>0)           //如果高位够减,直接减1
  156. (buf[i-1])--;    
  157. else                     //否则一直找到够减的位
  158. {
  159. j=i-1;
  160. while(buf[j]==0)     //j不会出现越界,是因为保证了最高位不为0
  161. buf[j--]=9;
  162. buf[j]=buf[j]-1;
  163. }
  164. }
  165. X=buf[i]-SB[i];              //将各位减的结果存入SC中
  166. SC[i]=X;
  167. }
  168. }
  169. /*---------------------------------------------------------------------------
  170. 功能:比较两个大数A和B的大小
  171. 入口参数:大数A和大数B
  172. 返回值:A>B:return 1 ; A=B:return 0 ; A<B:return -1
  173. ----------------------------------------------------------------------------*/
  174. int CRsaA::IntCmp(byteint A,byteint B)
  175. {
  176. int stat;
  177. stat=memcmp(A,B,DATALENGTH);    //系统函数
  178. if(stat==0)
  179. return 0;
  180. if(stat>0)
  181. return 1;
  182. return -1;
  183. }
  184. /*---------------------------------------------------------------------------
  185. 功能:得到一个大数的非零位数
  186. 入口参数:大数validtemp
  187. 返回值:大数中非零的位数
  188. ----------------------------------------------------------------------------*/
  189. int CRsaA::IntValid(byteint validtemp)
  190. {
  191. register i=0;
  192. while(validtemp[i]==0 && i<DATALENGTH)
  193. i++;
  194. return DATALENGTH-i;
  195. }
  196. /*---------------------------------------------------------------------------
  197. 功能:计算大数A÷B的结果,余数放在C中,商在D中
  198. 入口参数:被除数A,除数B,余数C,商D
  199. 返回值:无
  200. ----------------------------------------------------------------------------*/
  201. void CRsaA::SetMode(byteint A,byteint B,byteint C,byteint D)
  202. {
  203. register i,j,k;
  204. int valid_1,valid_2,valid,sbits,cmpval;
  205. byteint buf1,buf2;
  206.     
  207. SetZero(buf1);  SetZero(buf2);
  208. SetZero(D);                       //将大数D进行清零初始化
  209.     IntCpy(C,A);                      //将被除数A拷贝到C中
  210. valid_2=IntValid(B);              //计算B(除数)的位数,
  211. while((cmpval=IntCmp(C,B))>0)     //变除法为减法,每减一次就判断是否有C>B,如果满足就继续减。
  212. {
  213. valid_1=IntValid(C);          //计算C(被除数)的位数,因为它的位数在循环过程中是变化的
  214.                               //做减法后(C-B)仍然存放在C中
  215. valid=valid_1-valid_2;        //C的长度与B的长度的差(该值最小为0)
  216. if(valid>0)                   //如果被除数比除数的位数多
  217. {
  218. i=DATALENGTH-valid_1;     //被除数前导零的个数
  219. j=DATALENGTH-valid_2;     //除数前导零的个数,作下标指示器
  220. sbits=0;
  221. for(k=j;k<DATALENGTH;k++)
  222. {
  223. if(C[i]>B[j])         //从C和B的最高位开始依次比较对应位的大小,判断是否够减
  224. break;
  225. if(C[i]<B[j])
  226. {
  227. sbits=1;          //如果不够减,那么C就退一位,再做减法
  228. break;
  229. }
  230. i++;j++;              //当C和B的最高位相等时,就比较二者的次高位
  231. }
  232. valid=valid-sbits;
  233. SetZero(buf1);            //buf1清零
  234. for(i=valid;i<DATALENGTH;i++)
  235. {
  236. j=i-valid;
  237. buf1[j]=B[i];         //buf1中存放的是B左移若干位之后得到的值
  238.                       //如果够减,则B左移后最高位与C的最高位对齐,
  239.                       //否则与C的次高位对齐
  240. }
  241. }
  242. else
  243. IntCpy(buf1,B);           //当C和B的位数相同时,就直接把B放入缓冲区buf1中
  244. D[DATALENGTH-1-valid]++;      //这里保存的是在某一位上所做的减法的次数,每做一次就加1
  245. Substract(C,buf1,buf2);       //不论C的长度与B的长度的差是否大于0,都要做减法,直到C<=B
  246. IntCpy(C,buf2);
  247. }
  248. if(cmpval==0)                     //两个数相等
  249. {
  250. SetZero(C);                   //余数为0
  251. D[DATALENGTH-1]++;            //商为1
  252. }
  253. }
  254. /*---------------------------------------------------------------------------
  255. 功能:随机地产生一个大数奇数,长度为num,最高位不是0,存放在RandomA中
  256. 入口参数:大数A,长度num
  257. 返回值:无
  258. ----------------------------------------------------------------------------*/
  259. void CRsaA::IntRandom(byteint RandomA,int num)
  260. {
  261. int i;
  262. SetZero(RandomA);                     //将RandomA清零
  263. while(!(RandomA[DATALENGTH-1]%2))     //判断条件保证RandomA的最后一位数是奇数
  264. RandomA[DATALENGTH-1]=rand()%10;  //如果最后一位是偶数,则从新产生最后一位
  265.     while(!(RandomA[DATALENGTH-num]))     //判断条件保证RandomA最高位不是0
  266. RandomA[DATALENGTH-num]=rand()%10;//如果最高位是0,则从新产生最高位
  267. i=DATALENGTH-2;
  268. while(i>=DATALENGTH-num+1)            //循环产生从次低位开始到次高位的所有位上的数
  269. RandomA[i--]=rand()%10;
  270. }
  271. /*---------------------------------------------------------------------------
  272. 功能:将质数类型B拷贝到A中,实现类型转换
  273. 入口参数:大数A,质数类型B
  274. 返回值:无
  275. ----------------------------------------------------------------------------*/
  276. //功能:将数B拷贝到大数A,实现类型转换
  277. void CRsaA::LoadInt(byteint A,mtype B)
  278. {
  279. register i,j;
  280. SetZero(A);                  //A进行清零初始化
  281. i=DATALENGTH-1;
  282. j=MLENGTH-1;
  283. while(j>0)                   //循环拷贝各位数字
  284. {
  285. A[i--]=B[j--];
  286. }
  287. }
  288. /*---------------------------------------------------------------------------
  289. 功能:该函数用来从集合[1,b-1]中产生若干个用于检测的数,存放在Model[]中
  290. 入口参数:无
  291. 返回值:无
  292. ----------------------------------------------------------------------------*/
  293. void CRsaA::Mdata()
  294. {
  295. register i,j;                     //Randomly choose a set of 100 numbers in [1,b-1]
  296. int k=MLENGTH-2;
  297. memset(Model,0,TESTNUM*MLENGTH);  //这个函数在这里用来将整个数组清零,进行初始化
  298. srand( (unsigned)time( NULL ) );  //进行随机函数的初始化
  299. for(i=0;i<TESTNUM;i++)            //TESTNUM为需要产生的个数
  300. {
  301. for(j=MLENGTH-1;j>=k;j--)
  302. {
  303. Model[i][j]=rand()%10;    //注意这里与测试素数的程序中的区别,
  304. }
  305. if((memcmp(Model[i],mZEROVALUE,MLENGTH))==0)  
  306. i--;
  307. k--;                          //保证所产生的数不为0
  308. if (k<0) k=MLENGTH-2;
  309. }
  310. }
  311. /*---------------------------------------------------------------------------
  312. 功能:该函数用来将十进制的大整数转换成二进制的数
  313. 入口参数:需转换的大数B,二进制结果flag[400]
  314. 返回值:无
  315. ----------------------------------------------------------------------------*/
  316. void CRsaA::TransBi(byteint B,signed char flag[400])
  317. {
  318. byteint buf;
  319. byteint result;
  320. byteint temp;
  321. register i;
  322. SetZero(buf);  SetZero(result);  SetZero(temp);
  323. memset(flag,0,400);                     //将flag数组清零
  324. i=399;
  325. IntCpy(buf,B);                          //将B拷贝到buf中
  326. while(IntCmp(buf,ZEROVALUE)==1)         //如果buf内容为0
  327. {
  328. SetMode(buf,TWOVALUE,temp,result);  //将buf进行大数的模2运算,商在result中,余数temp
  329. flag[i]=temp[DATALENGTH-1];         
  330. IntCpy(buf,result);                 //对商继续进行模2运算
  331. i--;
  332. }
  333. flag[i]=-1;                             //设置一个标志位,表明二进制数的开始
  334. }
  335. /*---------------------------------------------------------------------------
  336. 功能:该函数用来进行模幂算法,A为底数,模为c,二进制的指数B存放在数组flag中
  337. 入口参数:底数A,模C,结果D,二进制质数flag[400]
  338. 返回值:A^B=1(mod C),返回1;A^B=p-1(mod C),返回2;否则返回0
  339. ----------------------------------------------------------------------------*/
  340. int CRsaA::PowerMode(byteint A,byteint C,byteint D,signed char flag[400])
  341. {
  342. byteint buf;
  343. byteint result;
  344. byteint temp,P;
  345. register i;
  346. SetZero(D);   SetZero(buf); SetZero(result); SetZero(temp); SetZero(P);  //将D清零
  347. IntCpy(temp,A);                       //将A的值拷贝到temp中
  348. if(flag[399]==1)                      //最低位为1,拷贝本身,flag[i]只有1或者0两种情况
  349. IntCpy(result,A);
  350. else   //最低位为0,则幂为1
  351. IntCpy(result,ONEVALUE);
  352. i=398;
  353. while(flag[i]!=-1)                    //判断是否已经到达指数尽头
  354. {
  355. Multiply(temp,temp,buf);          //temp*temp->buf 
  356. SetMode(buf,C,temp,P);            //buf%c余数->temp,商->p
  357. if(flag[i]!=0)                    //如果该位不是0,则将其和前一步低一位的结果进行乘法运算
  358. {                                 //否则,将其作为该位的模,在高一位的运算中,只要进行一次
  359. Multiply(temp,result,buf);    //平方运算,就可以得到高一位的模
  360. SetMode(buf,C,result,P);
  361. }
  362. i--;
  363. }                                     //result中存放的是最终结果
  364. IntCpy(buf,C);
  365. IntCpy(D,result);
  366. Substract(buf,ONEVALUE,temp);
  367. if(IntCmp(result,ONEVALUE)==0)        //p mod n=1,判断是否有A^B=1(mod C)
  368. return 1;
  369. if(IntCmp(result,temp)==0)            //p mod n=-1[p-1=-1(mod p)],判断是否有A^B=p-1(mod C)
  370. return 2;
  371. return 0;
  372. }
  373. /*---------------------------------------------------------------------------
  374. 功能:产生一个质数
  375. 入口参数:大数Prm
  376. 返回值:产生成功,返回0
  377. ----------------------------------------------------------------------------*/
  378. int CRsaA::Prime(byteint Prm)
  379. {
  380. int i,k,ok;
  381. signed char flag[400];
  382. byteint A,B,D,buf1,buf2;
  383. SetZero(A); SetZero(B); SetZero(D); SetZero(buf1); SetZero(buf2);
  384. while(1)                                 //一直循环直到找到一个素数为止
  385. {
  386. int pass=0;
  387. srand( (unsigned)time( NULL ) );     //初始化srand
  388. IntRandom(B,MLENGTH);                //随机产生一个大数B  try b if prime,B是一个奇数
  389. IntCpy(Prm,B);                       //将B拷贝到prm中 C=N result prime
  390. Substract(B,ONEVALUE,buf1);          //将B-ONEVALUE的结果放到buf1中
  391. SetMode(buf1,TWOVALUE,buf2,B);       //B=(B-1)/2的商,buf2=(B-1)/2的余数=0
  392. TransBi(B,flag);                     //将B转换为二进制大数
  393. ok=1;
  394. for(i=0;i<TESTNUM;i++)
  395. {
  396. LoadInt(A,Model[i]);             //将数组Model中的第i+1个数读取到A中
  397. k=PowerMode(A,Prm,D,flag);       //(A^flag) mod Prm ->D
  398. if(k!=1 && k!=2)                 //不符合判定规则
  399. {
  400. ok=0;
  401. break;
  402. }
  403. if(k==1)                         //判定条件1,G=A^(n-1)/2=1
  404. {
  405. }
  406. if(k==2)                         //判定条件2,G=A^(n-1)/2=p-1
  407. {
  408. }
  409. }
  410. if (ok)//if(ok && pass_2)
  411. {
  412. return 0;
  413. }//for循环用来检测IntRandom(B,MLENGTH)产生的数B是否是一个素数
  414. }
  415. }
  416. /*---------------------------------------------------------------------------
  417. 功能:计算公钥PK
  418. 入口参数:$(r)的值在Rvalue中,私钥SK,公钥PK
  419. 返回值:成功找到,返回1
  420. ----------------------------------------------------------------------------*/
  421. int CRsaA::ComputingPK(byteint Rvalue,byteint SK,byteint PK)
  422. {
  423. register i;
  424. byteint PA,PB,PC,buf1,temp,buf2;
  425. SetZero(PK); SetZero(PA); SetZero(PB); SetZero(PC); SetZero(buf1);   //清零初始化
  426. SetZero(temp); SetZero(buf2);
  427. while(1)
  428. {
  429. IntRandom(SK,SKLENGTH);        //随机产生一个大数奇数作为Generated secret key
  430. IntCpy(PB,SK);
  431. IntCpy(PA,Rvalue);
  432. while(1)
  433. {
  434. SetMode(PA,PB,PC,PK);     //PA=PB*PK+PC
  435. i=IntCmp(PC,ONEVALUE);
  436. if(i==0)                  //PC=1, i=0
  437. break;                //满足条件,是互质的
  438. i=IntCmp(PC,ZEROVALUE);
  439. if(i==0)
  440. {
  441. i=-1;                 //PC=0,i=-1
  442. break;                //不满足互质条件,跳出循环,从新生成一个随机数
  443. }
  444. IntCpy(PA,PB);            //按照欧几里的定理继续判断
  445. IntCpy(PB,PC);
  446. }
  447. if(i==0)                      //满足,跳出查找循环
  448. break;
  449. }
  450. IntCpy(temp,ONEVALUE);
  451. IntCpy(PA,Rvalue);
  452. IntCpy(PB,SK);
  453. while(1)
  454. {
  455. Multiply(PA,temp,buf1);  //buf1=PA*temp
  456. Plus(buf1,ONEVALUE,buf2);//buf2=(PA*temp)+1
  457. SetMode(buf2,PB,buf1,PK);//buf=((PA*temp)+1)%PB
  458. if(IntCmp(buf1,ZEROVALUE)==0)
  459. break;
  460. Plus(temp,ONEVALUE,buf1);
  461. IntCpy(temp,buf1);
  462. }
  463. return 1;                   //SK and PK found
  464. }
  465. /*---------------------------------------------------------------------------
  466. 功能:计算模R
  467. 入口参数:产生的质数p,q,模R
  468. 返回值:无
  469. ----------------------------------------------------------------------------*/
  470. void CRsaA::ComputingR(byteint p,byteint q,byteint R)
  471. {
  472. Multiply(p,q,R);              // R=p*q, public mode number
  473. }
  474. /*---------------------------------------------------------------------------
  475. 功能:计算$(r)
  476. 入口参数:质数p,质数q,模$(r)放在Rvalue
  477. 返回值:无
  478. ----------------------------------------------------------------------------*/
  479. void CRsaA::ComputingRvalue(byteint p,byteint q,byteint Rvalue)
  480. {
  481. byteint buf1,buf2;
  482. SetZero(buf1); SetZero(buf2);
  483. Substract(p,ONEVALUE,buf1);   // buf1=p-1
  484. Substract(q,ONEVALUE,buf2);   // buf2=q-1
  485. Multiply(buf1,buf2,Rvalue);   // Rvalue=(p-1)*(q-1)
  486. }
  487. /*---------------------------------------------------------------------------
  488. 功能:将接受的字符串转换为大数类型
  489. 入口参数:大数result,字符串input
  490. 返回值:数的长度
  491. ----------------------------------------------------------------------------*/
  492. int CRsaA::Getinput(byteint result,CString input)
  493. {
  494. int i=DATALENGTH,m=0;
  495. long strlen;
  496. strlen=input.GetLength();
  497. if(strlen==0) return 0;
  498. else
  499. {
  500. for(int j=0;j<strlen;j++)
  501. {
  502. result[i-strlen+j] = (input.GetAt(j)-'0');
  503. }
  504. return j;
  505. }
  506. }
  507. /*---------------------------------------------------------------------------
  508. 功能:实现加密,解密运算功能
  509. 入口参数:明文(大数类型source),模R,秘钥key,结果desti
  510. 返回值:无
  511. ----------------------------------------------------------------------------*/
  512. void CRsaA::RsaDo(byteint source,byteint R,byteint key,byteint desti)
  513. {
  514. TransBi(key,flag);
  515. PowerMode(source,R,desti,flag);
  516. }
  517. /*---------------------------------------------------------------------------
  518. 功能:将长整形的数转换为大数类型
  519. 入口参数:大数类型result,长整形input
  520. 返回值:成功,返回数的长度,否则返回0;
  521. ----------------------------------------------------------------------------*/
  522. int CRsaA::Getinput1(byteint result,unsigned long input)
  523. {
  524. int i=DATALENGTH-1,m=0;
  525. long j=0;
  526. int k=0;
  527. if(input)
  528. {
  529. do
  530. {
  531. j=input/10;
  532. k=input-j*10;
  533. result[i]=k;
  534. i--;
  535. m++;
  536. input=j;
  537. }while(j);
  538. return m;
  539. }
  540. else
  541. return 0;
  542. }
  543. /*---------------------------------------------------------------------------
  544. 功能:将十六进制的串转换为数值
  545. 入口参数:字符串指针
  546. 返回值:成功,返回数
  547. ----------------------------------------------------------------------------*/
  548. unsigned long CRsaA::Os2ip(unsigned char* pstr)
  549. {
  550. unsigned long ch=0;
  551. unsigned int j=0;
  552. unsigned long k=1;
  553. for(int i=0;i<4;i++)
  554. {
  555. j = (unsigned int) (*(pstr+3-i));
  556. /* if( (*(pstr+3-i))>='0'&&(*(pstr+3-i))<='9')
  557. j = (*(pstr+3-i)) - '0';
  558. if( (*(pstr+3-i))>='a'&&(*(pstr+3-i))<='f') 
  559. j = (*(pstr+3-i)) - 'a'+10;
  560. if( (*(pstr+3-i))>='A'&&(*(pstr+3-i))<='F')
  561. j = (*(pstr+3-i)) - 'A'+10;*/
  562. ch += j*k;
  563. k*=256;
  564. }
  565. return ch;
  566. /*---------------------------------------------------------------------------
  567. 功能:将数串转换为相应的字符串
  568. 入口参数:字符串str
  569. 返回值:返回转换的结果;
  570. ----------------------------------------------------------------------------*/
  571. CString CRsaA::Ip2os(CString str)
  572. {
  573. int strlen=str.GetLength(),quotient=0,remainder=0;
  574. unsigned long num=0,temp=0;
  575. unsigned int k=1;
  576. CString strResult="";
  577. for(int i=strlen;i>0;i--)  //得到相应的数字串,存放在num中
  578. {
  579. temp = (str.GetAt(i-1) - '0');
  580. num += temp*k;
  581. k *= 10;
  582. }
  583. //采用模除的方式,求得相应的十六进制数
  584. for(int j=0;j<4;j++)
  585. {
  586. quotient = num/256;
  587. remainder = num - quotient*256;
  588. /*if(remainder>=0&&remainder<=9)
  589. strResult.Insert(0,(remainder+'0'));
  590. if(remainder>=10&&remainder<=15)
  591. strResult.Insert(0,(remainder-10+'a'));*/
  592. strResult.Insert(0,(unsigned char)remainder);
  593. num = quotient;
  594. }
  595. return strResult; 
  596. }
  597. /*---------------------------------------------------------------------------
  598. 功能:产生RSA秘钥对
  599. 入口参数:存放结果的字符串地址 
  600. 返回值:无
  601. ----------------------------------------------------------------------------*/
  602. void CRsaA::GenKeys(CString& pk,CString& sk,CString& R)
  603. {
  604. byteint m_p,m_q,m_R,m_Rvalue,m_PK,m_SK;
  605. SetZero(m_p);      //对大数变量进行清零初始化
  606. SetZero(m_q);
  607.     SetZero(m_R);
  608.     SetZero(m_Rvalue);
  609.     SetZero(m_PK);
  610.     SetZero(m_SK);
  611. Mdata();         //生成比较数表
  612. AfxMessageBox("开始计算质数P...");
  613. Prime(m_p);        //生成素数p q
  614. AfxMessageBox("开始计算质数Q...");
  615. Prime(m_q);
  616. AfxMessageBox("开始计算模R...");
  617. ComputingR(m_p,m_q,m_R); //计算模R
  618. AfxMessageBox("开始计算模r");
  619. ComputingRvalue(m_p,m_q,m_Rvalue);  //计算r
  620. AfxMessageBox("开始计算秘钥SK,PK");
  621. ComputingPK(m_Rvalue,m_PK,m_SK);    // Generate PK and SK
  622. //CGenKeyBusyDlg dlg1;
  623. //g1.DoModal();
  624. R=PrtInt(m_R);
  625. pk=PrtInt(m_PK);
  626. sk=PrtInt(m_SK);
  627. return ;
  628. }
  629. /*---------------------------------------------------------------------------
  630. 功能:实现加密功能接口
  631. 入口参数:明文字符串source,模字符串R,秘钥字符串key,结果字符串数组result
  632. 返回值:无
  633. ----------------------------------------------------------------------------*/
  634. int CRsaA::RsaEncrypt(CString& source,const char *key,const char *R,CStringArray& result)
  635. {
  636. unsigned char* pstr;
  637. int j;//sourcelen,j;
  638. byteint m_key,m_R,desti,aa;
  639. SetZero(desti);                         //将大数变量清零初始化
  640. SetZero(aa);
  641. //SetZero(bb);
  642. SetZero(m_key);
  643. SetZero(m_R);
  644. pstr = (unsigned char*)(LPCTSTR)source; //得到字符串数据的指针
  645. j = source.GetLength()/4;               //得到数组的元素个数
  646. result.SetSize(j,1);
  647. Getinput(m_key,key);                    //将字符串转换为大数类型
  648. Getinput(m_R,R);
  649. for(int i=0;i<j;i++)
  650. {
  651. Getinput1(desti,Os2ip(pstr));       //将四个字节的输入转换为大数类型数值
  652. RsaDo(desti,m_R,m_key,aa);          //进行加密运算
  653. result.SetAt(i,PrtInt(aa));         //将结果存放到数组中
  654. SetZero(desti);  SetZero(aa);
  655. pstr += 4;
  656. }
  657. return j;
  658. }
  659. /*---------------------------------------------------------------------------
  660. 功能:实现解密功能接口
  661. 入口参数:密文字符串数组source,秘钥字符串sk,模字符串R,
  662. 返回值:结果字符串数组result
  663. ----------------------------------------------------------------------------*/
  664. CString CRsaA::RsaDecrypt(CStringArray& source,const char* sk,const char* R)
  665. {
  666. int index=0;
  667. CString result;
  668. byteint m_sk,m_r,desti,aa;
  669. SetZero(m_sk);  SetZero(m_r); SetZero(desti); SetZero(aa);  //SetZero(bb);
  670. index=source.GetSize();   //得到数组的元素个数
  671. Getinput(m_sk,sk);        //将字符串转换为大数类型
  672. Getinput(m_r,R);
  673. for(int i=0;i<index;i++)
  674. {
  675. Getinput(desti,source.GetAt(i));   //将加密结果转换为大数类型
  676. RsaDo(desti,m_r,m_sk,aa);          //解密运算
  677. result += Ip2os(PrtInt(aa));       //组合初始明文
  678. SetZero(aa);  SetZero(desti);
  679. }
  680. return result;        //返回明文串
  681. }
  682. /*---------------------------------------------------------------------------
  683. 功能:生成一个秘钥存贮文件
  684. 入口参数:无
  685. 返回值:无
  686. ----------------------------------------------------------------------------*/
  687. void CRsaA::GenKeysTable()
  688. {
  689. CStringArray RArray,SKArray,PKArray;
  690. CString r,pk,sk;
  691. int j=1,i;      //参数j表示产生的秘钥对的个数
  692. unsigned char strlength;
  693. //设置数组的元素个数
  694. RArray.SetSize(j,1); SKArray.SetSize(j,1); PKArray.SetSize(j,1);
  695. /*-----------------------------------------------------------------------
  696. 文件格式为:
  697. 长度   秘钥   长度   秘钥......
  698. ----   ----   ----   ----
  699. 1byte  nbyte  1byte  nbyte       (中间无空格,R,SK,PK)
  700. */
  701. CFile file;
  702. for(i=0;i<j;i++)
  703. {
  704. GenKeys(pk,sk,r);  //循环产生秘钥
  705. RArray.SetAt(i,r); SKArray.SetAt(i,sk); PKArray.SetAt(i,pk);
  706. }
  707. //if(file.Open("c:\key.txt",CFile::modeCreate|CFile::modeReadWrite)==0)
  708. if(file.Open("key.txt",CFile::modeCreate|CFile::modeReadWrite)==0)
  709. {
  710. AfxMessageBox("open file error!");  //打开文件失败
  711. return;
  712. }
  713. for(i=0;i<j;i++)
  714. {                //循环写入结果
  715. strlength = (unsigned char)(RArray.GetAt(i)).GetLength();
  716. file.Write(&strlength,1);
  717. file.Write(RArray.GetAt(i),(RArray.GetAt(i)).GetLength());
  718. strlength = (unsigned char)(SKArray.GetAt(i)).GetLength();
  719. file.Write(&strlength,1);
  720. file.Write(SKArray.GetAt(i),(SKArray.GetAt(i)).GetLength());
  721. strlength = (unsigned char)(PKArray.GetAt(i)).GetLength();
  722. file.Write(&strlength,1);
  723. file.Write(PKArray.GetAt(i),(PKArray.GetAt(i)).GetLength());
  724. }
  725. file.Close();
  726. }
  727. void CRsaA::LoadKeysFromFile(CString& r,CString& sk,CString& pk)
  728. {
  729. int            j=10,len;
  730. char           *pbuffer;
  731. unsigned char  strlen1;
  732. CFile          file;
  733. CFileException e;
  734. CString        strFileName;
  735. if(file.Open("c:\key.txt",CFile::modeRead)==0)
  736. {
  737. AfxMessageBox("File(key.txt)could not be opened" );
  738. }
  739. file.Read(&strlen1,1);  //读出R长度
  740. len = (int)strlen1;
  741. pbuffer = new char[len+1];
  742. pbuffer[len]='';
  743. file.Read(pbuffer,len);  //读出R
  744. r=pbuffer;
  745. delete pbuffer;
  746. file.Read(&strlen1,1);  //读出SK长度
  747. len = (int)strlen1;
  748. pbuffer = new char[len+1];
  749. pbuffer[len]='';
  750. file.Read(pbuffer,len);  //读出SK
  751. sk=pbuffer;
  752. delete pbuffer;
  753. file.Read(&strlen1,1);  //读出PK长度
  754. len = (int)strlen1;
  755. pbuffer = new char[len+1];
  756. pbuffer[len]='';
  757. file.Read(pbuffer,len);  //读出PK
  758. pk=pbuffer;
  759. delete pbuffer;
  760. file.Close();
  761. }