RSA算法 是一種公鑰加密算法,RSA算法相比別的算法思路非常清晰,但是想要破解的難度非常大。RSA算法基於一個非常簡單的數論事實:兩個素數相乘得到一個大數很容易,但是由一個大數分解為兩個素數相乘卻非常難。這種算法是在1978年首次亮相,它是第一個既能用於數據加密也可以用於數字簽名的算法,而且理解起來簡單容易。早在1973,就有密碼學家發現了類似的算法,但是一直被列為絕密直到1998年才被正式公開出來。
RSA算法是一種非對稱的算法,該算法需要一對密鑰使用其中一個加密另一個就可以進行解密。首先我們來認識一下歐拉函數:
歐拉函數的通式形如:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),計算出來的值是小於x的自然數中素數的個數,關於正確性數論上有嚴格的證明。
在RSA算法中我們的初始的兩個素數是p和q,而歐拉函數的參數x就是p*q,那么歐拉函數就可以變形為:φ(p*q)=(p-1)*(q-1)
然后我們需要以下兩個步驟來計算出一對可以用來進行加密和解密的密鑰:
(1)找到任意一個數d,使得d和p*q互質,即gcd(d,p*q)=1(最大公約數 of greatest common divisor)
(2)計算出一個e,滿足gcd(d*e,p*q)=1
比如舉p=3,q=7為例子,那么假設使d=5滿足gcd(21,5)=1,那么對應的e就應該滿足gcd(5*e,21)=1,得e=17,這樣一來我們就得到了一對公鑰和密鑰d,e。
假設要加密數據3,那么就有(3)^d mod p*q=243mod21=12 所以加密之后我們得到的數據就是12
對於解密過程,我們對加密后的數據 (12)^e mod p*q=12^17mod21=(12^5)mod21 * (12^5)mod 21 * (12^5)mod21 * (12)^2mod21=((7^3)mod21)*3mod21=3
整個RSA加密解密算法的過程簡單的有些令人擔憂他的安全性,但是上圖給了我們一個肯定的答復,隨着RSA密鑰長度的增加,保密的年限會加速增長,在當今現代如果不考慮量子計算機暴力破解的話,RSA算法的加密的安全是可以保證的,除非數學界會有發現新的方法可以快速算出一個大數(可以非常大)分為兩個質數的乘積的算法。
有了以上的基礎我們就可以對長的數據進行分組從而完成加密處理:
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 5 #define KEY_LEN_LIMIT 1024 6 7 #define TRUE 1 8 #define FALSE 0 9 10 unsigned prime1,prime2; 11 char buf[KEY_LEN_LIMIT]={}; 12 unsigned pub,sec=2; 13 14 15 void swap(unsigned*l,unsigned*r){ 16 unsigned tmp=*l; 17 *l=*r; 18 *r=tmp; 19 } 20 21 unsigned gcd(unsigned a,unsigned b){ 22 if(a<b)swap(&a,&b); 23 if(b==0)return a; 24 else return gcd(b,a%b); 25 } 26 27 28 void encrypt(char*p,unsigned key,unsigned mod){ 29 char tmp=*p; 30 for(unsigned i=2;i<=key;i++){ 31 tmp=(tmp*tmp)%mod; 32 } 33 *p=tmp; 34 } 35 36 void decrypt(char*p,unsigned key,unsigned mod){ 37 char tmp=*p; 38 for(unsigned i=2;i<=key;i++){ 39 tmp=(tmp*tmp)%mod; 40 } 41 *p=tmp; 42 } 43 44 int main(int argc,char*argv[]){ 45 printf("Input Your Primary Letter/Number 1st to Generate Key:"); 46 scanf("%u",&prime1); 47 printf("Input Your Primary Letter/Number 2nd to Generate Key:"); 48 scanf("%u",&prime2); 49 unsigned tmp1=(unsigned)prime1,tmp2=(unsigned)prime2; 50 unsigned mul=(tmp1-1)*(tmp2-1); 51 printf("Input Your 1st Public Key:"); 52 scanf("%u",&pub); 53 while(gcd(pub,mul)!=1){ 54 printf("Input Your 1st Public Key:(Illegal)"); 55 scanf("%u",&pub); 56 } 57 printf("Now The Secret Key is:"); 58 while(((pub*sec)%mul)!=1)sec++; 59 printf("%u\n",sec); 60 printf("Finally Input Your Plain Text to Encrypt:"); 61 scanf("%s",buf); 62 printf("The Encrypted Text is:"); 63 for(int i=0;i<KEY_LEN_LIMIT;i++){ 64 if(buf[i]==0)break; 65 else{ 66 encrypt(&buf[i],pub,mul); 67 printf("%u",buf[i]); 68 } 69 }putchar('\n'); 70 printf("The Decrypted Text is:"); 71 for(int i=0;i<KEY_LEN_LIMIT;i++){ 72 if(buf[i]==0)break; 73 else{ 74 decrypt(&buf[i],sec,mul); 75 printf("%c",buf[i]); 76 } 77 }putchar('\n'); 78 return 0; 79 }