一、公鑰密碼體制的概念由Diffie和Hellman於1976年提出,用於解決對稱密碼體制中密鑰分配的問題。在公鑰密碼體制中,密鑰被分爲公鑰與私鑰,公鑰是公開的,用於加密;私鑰是保密的,用於解密。通過四十餘年的研究發展,RSA密碼、ElGamal密碼、橢圓曲線密碼等等公鑰密碼體制在商業、軍事上都已經獲得了普遍的應用。ios
二、RSA密碼由R. Rivest、A. Shamir和L. Adleman於1977年提出,是最著名的公鑰密碼,可以抵抗到目前爲止已知的絕大多數密碼攻擊,已被ISO推薦爲公鑰數據加密標準。RSA密碼的安全性基於這樣一個事實:將兩個大素數p,q相乘十分容易,但對其乘積N=pq做因子分解卻極其困難。在本實驗中,假設p,q均爲len比特素數,具體描述以下:算法
系統參數數組
大素數p、q:len比特素數(即 且p、q爲素數)安全
乘積N:N = p*q,約爲2*len比特函數
N的歐拉函數值:oop
公鑰測試
(N,e):其中e知足1<e<且gcd (e, ) = 1加密
私鑰spa
(N,d):其中d知足1<d<且,即code
明文
正整數m:知足1<m<N-1
加密
密文
解密
密文
RSA密鑰生成
1)生成指定bit數的隨機奇數A
2)利用MillerRabin素性檢測算法判斷A是否爲素數,若通
過,令p=A,不然返回1)繼續作,直到經過爲止
3)利用一樣的方法生成q
單次MillerRabin素性檢測算法:
要測試N是否爲素數,首先將N-1分解成
再隨機選擇,若對全部的,都有
則N是合數,不然,有不小於3/4的機率是素數。
屢次MillerRabin素性檢測算法:
循環調用單次MillerRabin素性檢測算法,若調用次數爲loop,則合數經過素性測試(即該算法錯誤機率)將不超過(1/4)^loop,本次實驗中,建議loop取20便可。
參考代碼:
1 #include <iostream> 2 #include <time.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <math.h> 6 7 #define SIZE 68 8 #define MIN 0 9 #define MAX 255 10 11 using namespace std; 12 13 typedef struct Bigint 14 { 15 unsigned char num[SIZE]; 16 }Bigint; 17 18 typedef struct Bigint2 19 { 20 unsigned char num[2*SIZE]; 21 }bigint2; 22 23 Bigint BigRand(int bytes);//隨機生成一個bit爲8*bytes的數 24 Bigint BigRand(Bigint n);//生成1到n之間的隨機數 25 void Print(Bigint a);//輸出Bigint a 26 void Print(Bigint2 a);//輸出Bigint2 a 27 int Compare(Bigint a,Bigint b);//比較a,b大小 28 int Compare(Bigint2 a,Bigint2 b);//比較a,b大小 29 Bigint ByteMoveLeft(Bigint a,int n);//將a擴大n*256倍後輸出 30 Bigint2 ByteMoveLeft(Bigint2 a,int n);//將a擴大n*256倍後輸出 31 void BitMoveRight(Bigint &a);//縮小一個比特(2倍) 32 Bigint Add(Bigint a,Bigint b);//Bigint a與b相加 33 Bigint Sub(Bigint a,Bigint b);//Bigint a-b 34 Bigint2 Sub(Bigint2 a,Bigint2 b);//Bigint2 a-b 35 Bigint2 Mul(Bigint a,Bigint b);//a*b 36 Bigint Div(Bigint a,Bigint b);//Bigint a/b 37 void Print10(Bigint a);//以10進制輸出Bigint a 38 void Print10(Bigint2 a);//以10進制數處Bigint2 a 39 int Length(Bigint a);//輸出a的長度 40 int Length(Bigint2 a); 41 Bigint2 Mod(Bigint2 a, Bigint2 b); // 求餘: 輸入a,b, 返回 a % b 42 Bigint Mod(Bigint a, Bigint b);// 求餘: 輸入a,b, 返回 a % b 43 void Copy(Bigint &a, Bigint b);//複製 44 Bigint2 Extend(Bigint a);//擴充數組 45 Bigint Narrow(Bigint2 a);//截斷數組 46 Bigint AddMod(Bigint a,Bigint b,Bigint n);//計算(a+b)mod n 47 Bigint SubMod(Bigint a,Bigint b,Bigint n);//計算(a-b)mod n(a>b) 48 Bigint Sub2Mod(Bigint a,Bigint b,Bigint n);//計算(a-b)mod n 49 Bigint MulMod(Bigint a,Bigint b,Bigint n);//計算(a*b)mod n 50 Bigint PowMod(Bigint a,Bigint b,Bigint n);//計算(a^b)mod n 51 bool MillerRabinKnl(Bigint &n); //單次檢測, 經過返回1, 不然返回0 52 bool MillerRabin(Bigint &n, long loop); //屢次素性檢測 53 Bigint get1n(int bytes);//隨機生成一個長爲8*bytes的奇數 54 Bigint Encrypt(Bigint m, Bigint e, Bigint N); //計算c = m^e mod N 55 Bigint Decrypt(Bigint c, Bigint d, Bigint N); //計算m = c^d mod N 56 57 58 59 Bigint BigRand(int bytes)//隨機生成一個bit爲8*bytes的數 60 { 61 Bigint pq; 62 srand((unsigned)time(NULL)); 63 for(int i=0;i<bytes;i++) 64 { 65 pq.num[i]=(unsigned char)(rand()%(MAX-MIN+1)+MIN); 66 } 67 for(int i=bytes;i<SIZE;i++) 68 pq.num[i]='\0'; 69 return pq; 70 } 71 72 int Length(Bigint a) 73 { 74 int len; 75 for(int i=SIZE-1;i>=0;i--) 76 { 77 if(a.num[i]!='\0') 78 { 79 len=i+1; 80 break; 81 } 82 else 83 len=i; 84 } 85 return len; 86 } 87 88 int Length(Bigint2 a) 89 { 90 int len; 91 for(int i=2*SIZE-1;i>=0;i--) 92 { 93 if(a.num[i]!='\0') 94 { 95 len=i+1; 96 break; 97 } 98 else 99 len=i; 100 } 101 return len; 102 } 103 104 void Copy(Bigint &a,Bigint b) 105 { 106 for(int i=0;i<SIZE;i++) 107 { 108 a.num[i]=b.num[i]; 109 } 110 return; 111 } 112 113 Bigint2 Extend(Bigint a) 114 { 115 Bigint2 b={0}; 116 for(int i=0;i<Length(a);i++) 117 { 118 b.num[i]=a.num[i]; 119 } 120 return b; 121 } 122 123 Bigint Narrow(Bigint2 a) 124 { 125 Bigint b={0}; 126 for(int i=0;i<SIZE;i++) 127 { 128 b.num[i]=a.num[i]; 129 } 130 return b; 131 } 132 133 Bigint BigRand(Bigint n)//生成1到n之間的隨機數 134 { 135 Bigint a; 136 int len; 137 srand((unsigned)time(NULL)); 138 len=rand()%(Length(n)-1)+1; 139 a=BigRand(len); 140 while(Compare(a,n)>=0||(Length(a)==1&&(int)a.num[0]==0)) 141 { 142 srand((unsigned)time(NULL)); 143 len=rand()%(Length(n)-1)+1; 144 a=BigRand(len); 145 } 146 return a; 147 } 148 149 void Print(Bigint a)//輸出Bigint a; 150 { 151 if(Length(a)==0) 152 cout<<'0'<<endl; 153 else 154 for(int i=Length(a)-1;i>=0;i--) 155 { 156 cout.width(3); 157 cout<<(int)a.num[i]<<','; 158 } 159 cout<<endl; 160 } 161 162 void Print(Bigint2 a)//輸出Bigint2 a; 163 { 164 if(Length(a)==0) 165 cout<<'0'<<endl; 166 else 167 for(int i=Length(a)-1;i>=0;i--) 168 { 169 cout.width(3); 170 cout<<(int)a.num[i]<<','; 171 } 172 cout<<endl; 173 } 174 175 int Compare(Bigint a,Bigint b)//比較a與b的大小 176 { 177 int max,len_a,len_b; 178 len_a=Length(a); 179 len_b=Length(b); 180 if(len_a>len_b) 181 return 1; 182 else if(len_a<len_b) 183 return -1; 184 else 185 max=len_a; 186 for(int i=max-1;i>=0;i--) 187 { 188 if(a.num[i]>b.num[i]) 189 return 1; 190 if(a.num[i]<b.num[i]) 191 return -1; 192 } 193 return 0; 194 } 195 196 int Compare(Bigint2 a,Bigint2 b)//比較大小 197 { 198 int max,len_a,len_b; 199 len_a=Length(a); 200 len_b=Length(b); 201 if(len_a>len_b) 202 return 1; 203 else if(len_a<len_b) 204 return -1; 205 else 206 max=len_a; 207 for(int i=max-1;i>=0;i--) 208 { 209 if(a.num[i]>b.num[i]) 210 return 1; 211 if(a.num[i]<b.num[i]) 212 return -1; 213 } 214 return 0; 215 } 216 217 Bigint Add(Bigint a,Bigint b)//Bigint a+b 218 { 219 Bigint c; 220 int Carry=0,temp,i,max; 221 for(int i=0;i<SIZE;i++) 222 { 223 temp=(int)a.num[i]+(int)b.num[i]+Carry; 224 Carry=temp/256; 225 temp=temp%256; 226 c.num[i]=(char)temp; 227 } 228 return c; 229 } 230 231 Bigint Sub(Bigint a,Bigint b)//Bigint a-b 232 { 233 int temp,i,Carry=0,n; 234 Bigint c; 235 n=Compare(a,b); 236 if(n==-1) 237 { 238 cout<<"Subtract error!"<<endl; 239 return a; 240 } 241 else//執行a-b 242 { 243 for(i=0;i<SIZE;i++) 244 { 245 if((int)a.num[i]-Carry>=(int)b.num[i]) 246 { 247 temp=(int)a.num[i]-Carry-(int)b.num[i]; 248 Carry=0; 249 } 250 else 251 { 252 temp=(int)a.num[i]-Carry+256-(int)b.num[i]; 253 Carry=1; 254 } 255 c.num[i]=(unsigned char)temp; 256 } 257 } 258 return c; 259 } 260 261 Bigint2 Sub(Bigint2 a,Bigint2 b)//Bigint2 a-b 262 { 263 int temp,i,Carry=0,n; 264 Bigint2 c; 265 n=Compare(a,b); 266 if(n==-1) 267 { 268 cout<<"Subtract error!"<<endl; 269 return a; 270 } 271 else//執行a-b 272 { 273 for(i=0;i<2*SIZE;i++) 274 { 275 if((int)a.num[i]-Carry>=(int)b.num[i]) 276 { 277 temp=(int)a.num[i]-Carry-(int)b.num[i]; 278 Carry=0; 279 } 280 else 281 { 282 temp=(int)a.num[i]-Carry+256-(int)b.num[i]; 283 Carry=1; 284 } 285 c.num[i]=(unsigned char)temp; 286 } 287 } 288 return c; 289 } 290 291 Bigint2 Mul(Bigint a,Bigint b)//a*b 292 { 293 Bigint2 c={0}; 294 int Carry=0,temp; 295 int i,j; 296 for(i=0;i<SIZE;i++) 297 { 298 for(j=0;j<SIZE;j++) 299 { 300 temp=(int)a.num[i]*(int)b.num[j]+(int)c.num[i+j]+Carry; 301 Carry=temp/256; 302 temp=temp%256; 303 c.num[i+j]=(unsigned char)temp; 304 } 305 } 306 c.num[2*SIZE-1]=(unsigned char)Carry; 307 return c; 308 } 309 310 Bigint ByteMoveLeft(Bigint a,int n)//將a擴大n*256倍後輸出 311 { 312 Bigint c={0}; 313 int i; 314 for(i=Length(a)-1;i>=0;i--) 315 { 316 c.num[i+n]=a.num[i]; 317 } 318 for(i=0;i<n;i++) 319 c.num[i]='\0'; 320 return c; 321 } 322 323 Bigint2 ByteMoveLeft(Bigint2 a,int n)//將a擴大n*256倍後輸出 324 { 325 Bigint2 c={0}; 326 int i; 327 for(i=Length(a)-1;i>=0;i--) 328 { 329 c.num[i+n]=a.num[i]; 330 } 331 for(i=0;i<n;i++) 332 c.num[i]='\0'; 333 return c; 334 } 335 336 void BitMoveRight(Bigint &a)//縮小一個比特(2倍) 337 { 338 Bigint b={2}; 339 a=Div(a,b); 340 return; 341 } 342 343 Bigint Div(Bigint a,Bigint b)//Bigint a/b 344 { 345 int len; 346 Bigint B={0}; 347 Bigint c={0}; 348 len=Length(a)-Length(b); 349 while(len>=0) 350 { 351 B=ByteMoveLeft(b,len); 352 while(Compare(a,B)>=0) 353 { 354 a=Sub(a,B); 355 c.num[len]++; 356 } 357 len--; 358 } 359 return c; 360 } 361 362 Bigint Mod(Bigint a,Bigint b)//計算Bigint a%b 363 { 364 if(Compare(a,b)<0) 365 return a; 366 else 367 { 368 Bigint B={0}; 369 int len=Length(a)-Length(b); 370 while(len>=0) 371 { 372 B=ByteMoveLeft(b,len); 373 while(Compare(a,B)>=0) 374 { 375 a=Sub(a,B); 376 } 377 len--; 378 } 379 } 380 return a; 381 } 382 383 Bigint2 Mod(Bigint2 a,Bigint2 b)//計算Bigint2 a%b 384 { 385 if(Compare(a,b)<0) 386 return a; 387 else 388 { 389 Bigint2 B={0}; 390 int len=Length(a)-Length(b); 391 while(len>=0) 392 { 393 B=ByteMoveLeft(b,len); 394 while(Compare(a,B)>=0) 395 { 396 a=Sub(a,B); 397 } 398 len--; 399 } 400 } 401 return a; 402 } 403 404 Bigint Mod10(Bigint a)//Bigint a對10作模運算 405 { 406 Bigint n={0}; 407 for(int i=0;i<Length(a);i++) 408 { 409 n.num[0]=((int)n.num[0]%10+(((int)a.num[i]%10)*(int)pow(6,i))%10)%10; 410 } 411 return n; 412 } 413 414 void Print10(Bigint a) //十進制打印輸出 415 { 416 int res[2000]; 417 int i = 0; 418 Bigint b = {0}; 419 Bigint c = {10}; 420 if(Length(a) == 0) //若a==0,則輸出0 421 { 422 cout<<0<<endl; 423 return; 424 } 425 Bigint d={0}; 426 while(Compare(a,b) == 1) 427 { 428 d=Mod(a,c); 429 res[i]=(int)d.num[0]; 430 a = Div(a,c); 431 i++; 432 } 433 for(int j = i-1; j>=0; j--) 434 { 435 cout<<res[j]; 436 } 437 cout<<endl; 438 } 439 440 Bigint AddMod(Bigint a,Bigint b,Bigint n) 441 { 442 Bigint c={0}; 443 c=Add(a,b); 444 c=Mod(c,n); 445 return c; 446 } 447 448 Bigint SubMod(Bigint a,Bigint b,Bigint n)//計算(a-b)mod n(a>b) 449 { 450 Bigint c={0}; 451 if(Compare(a,b)<0) 452 { 453 cout<<"ERROR!"<<endl; 454 return c; 455 } 456 else 457 { 458 c=Sub(a,b); 459 c=Mod(c,n); 460 } 461 return c; 462 } 463 464 Bigint Sub2Mod(Bigint a,Bigint b,Bigint n)//計算(a-b)mod n 465 { 466 Bigint c={0}; 467 if(Compare(a,b)<0) 468 { 469 c=Sub(Add(a,n),b); 470 c=Mod(c,n); 471 } 472 else 473 { 474 c=Sub(a,b); 475 c=Mod(c,n); 476 } 477 return c; 478 } 479 480 Bigint MulMod(Bigint a,Bigint b,Bigint n)//計算(a*b)mod n 481 { 482 Bigint2 C={0},N={0}; 483 Bigint c={0}; 484 a=Mod(a,n); 485 b=Mod(b,n); 486 C=Mul(a,b); 487 N=Extend(n); 488 C=Mod(C,N); 489 c=Narrow(C); 490 return c; 491 } 492 493 Bigint PowMod(Bigint a,Bigint b,Bigint n)//計算(a^b)mod n 494 { 495 Bigint c = {1}; 496 Bigint temp = {1}; 497 while(Length(b) > 0) 498 { 499 while(!(b.num[0] & 0x01)) 500 { 501 BitMoveRight(b); 502 a = MulMod(a,a,n); 503 } 504 b = Sub(b,temp); 505 c = MulMod(a,c,n); 506 } 507 return c; 508 } 509 510 bool MillerRabinKnl(Bigint &n) //單次檢測, 經過返回1, 不然返回0 511 { 512 Bigint b,m,v,temp; 513 Bigint j = {0}; 514 Bigint one = {1}; 515 Bigint two = {2}; 516 Bigint three = {3}; 517 m = Sub(n,one); 518 while(!(m.num[0] & 0x01)) //計算m, j,使得 n-1=2^j * m 519 { 520 j = Add(j,one); 521 BitMoveRight(m); 522 } 523 b = Add(two, BigRand(Sub(n,three))); //隨機取一個 524 v = PowMod(b,m,n); //計算 525 if(Compare(v,one) == 0) //若v=1,經過測試 526 return 1; 527 528 Bigint i = {1}; 529 temp = Sub(n,one); 530 while(Compare(v,temp) < 0) //若v<n-1,不經過 531 { 532 if(Compare(i,j) == 0) //若i=j,是合數,不經過 533 return 0; 534 v = MulMod(v,v,n); //, i=i+1 535 i = Add(i,one); 536 } 537 return 1; //若v=n-1, 經過測試 538 } 539 540 bool MillerRabin(Bigint &n, long loop) //屢次素性檢測 541 { 542 for(long i = 0; i<loop;i++) 543 { 544 if(!MillerRabinKnl(n)) 545 return 0; 546 } 547 return 1; 548 } 549 550 Bigint get1n(int bytes)//隨機生成一個長爲8*bytes的奇數 551 { 552 Bigint n={0}; 553 while(!(n.num[0] & 0x01)) 554 { 555 n=BigRand(bytes); 556 } 557 return n; 558 } 559 560 bool Inverse(Bigint phiN, Bigint e, Bigint &d) 561 { 562 Bigint zero ={0}; 563 Bigint one = {1}; 564 Bigint y2 = {1}; 565 Bigint x2 = {0}; 566 Bigint x3,y3,t2,t3,q; 567 Copy(x3, phiN); 568 Copy(y3, e); 569 while(1) 570 { 571 if(Length(y3) == 0) //若y3=0,求逆失敗,返回0 572 return 0; 573 if(Length(y3) == 1 && y3.num[0] == 1) 574 { //若y3=1,求逆成功,令d=y2,並返回1 575 Copy(d,y2); 576 return 1; 577 } 578 q = Div(x3,y3); //利用與展轉相除法相似的方法 579 t2 = Sub2Mod(x2,MulMod(q,y2,phiN),phiN); 580 //t2 = (x2 - q*y2) mod phiN,模是爲了避免出現負數 581 t3 = Sub(x3,Narrow(Mul(q,y3))); // t3 = x3-q*y3 582 Copy(x2,y2); 583 Copy(x3,y3); 584 Copy(y2,t2); 585 Copy(y3,t3); 586 } 587 } 588 589 Bigint Encrypt(Bigint m, Bigint e, Bigint N) //計算c = m^e mod N 590 { 591 Bigint c; 592 c=PowMod(m,e,N); 593 return c; 594 } 595 596 Bigint Decrypt(Bigint c, Bigint d, Bigint N) //計算m = c^d mod N 597 { 598 Bigint m; 599 m=PowMod(c,d,N); 600 return m; 601 } 602 603 Bigint GetP_Q(int bytes)//獲得8*bytes的pq 604 { 605 Bigint pq={0}; 606 pq=get1n(bytes); 607 while(!(MillerRabin(pq,20))) 608 { 609 pq=get1n(bytes); 610 } 611 return pq; 612 } 613 614 int main() 615 { 616 Bigint p,q,d,m,c,phiN,N,m1; 617 Bigint e={1,0,1}; 618 Bigint one={1}; 619 p=GetP_Q(32); 620 sleep(1); 621 q=GetP_Q(32); 622 N=Narrow(Mul(p,q)); 623 phiN=Narrow(Mul(Sub(p,one),Sub(q,one))); 624 while(!(Inverse(phiN,e,d))) 625 { 626 p=GetP_Q(32); 627 sleep(1); 628 q=GetP_Q(32); 629 N=Narrow(Mul(p,q)); 630 phiN=Narrow(Mul(Sub(p,one),Sub(q,one))); 631 } 632 m=BigRand(64); 633 c=Encrypt(m,e,N); 634 m1=Decrypt(c,d,N); 635 cout<<"生成大素數:"<<endl; 636 cout<<"p="; 637 Print10(p); 638 cout<<"q="; 639 Print10(q); 640 cout<<endl<<"系統的參數是:"<<endl; 641 cout<<"N="; 642 Print10(N); 643 cout<<endl<<"公鑰是:"<<endl; 644 cout<<"e="; 645 Print10(e); 646 cout<<endl<<"私鑰是:"<<endl; 647 cout<<"d="; 648 Print10(d); 649 cout<<endl<<"明文是:"<<endl; 650 cout<<"m="; 651 m=Mod(m,N); 652 Print10(m); 653 cout<<endl<<"加密獲得的密文:"<<endl; 654 cout<<"c="; 655 Print10(c); 656 cout<<endl<<"解密獲得的明文:"<<endl; 657 cout<<"m1="; 658 Print10(m1); 659 Bigint a; 660 /*a=MulMod(e,d,phiN); 661 Print10(a);*/ 662 return 0; 663 }
運行後獲得的結果(不惟一):