日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

C语言实现RSA

發布時間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言实现RSA 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考 《密碼學引論》武漢大學出版社

RSA簡介

1978年美國麻省理工學院的三名密碼學者R.L.Rivest, A.Shamir和L.M.Adleman提出了一種基于大合數因子分解困難性的公開密鑰密碼,簡稱RSA密碼。

RSA密碼被譽為是一種風格幽雅的公開密鑰密碼。由于RSA密碼即可用于加密,又可用于數字簽名,安全、易懂。因此,RSA密碼已成為目前應用最廣泛的公開密鑰密碼。許多國家標準化組織,如ISO,ITU和SWIFT等都已接受RSA作為標準。Internet網的E-Mail保密系統CPG以及國際的VISA和MASTER組織的電子商務協議(SET協議)中都將RSA密碼作為傳送會話密鑰和數字簽名的標準。

RSA加解密過程

  1. 隨機地選擇兩個大素數p和q,而且保密;
  2. 計算n=pq,將n公開
  3. 計算fi=(p-1)*(q-1),對fi保密
  4. 隨機選擇一個正整數e,1<e<fi 且e和fi 互素
  5. 根據 ed=1 mod fi,求出d,并對d保密
  6. 加密運算:C=M^e mod n
  7. 解密運算:M=C^d mod n

簡單實現

#include<stdio.h> int main(){int p=3,q=5;int n=p*q,fi=(p-1)*(q-1);int e=3,d;int i;for(i=0;i<fi;i++){if((i*e)%fi==1){d=i;break;}}printf("p:%d q:%d n:%d fi:%d e:%d d:%d\n",p,q,n,fi,e,d);int m=7,c=1,tmp=1;for(i=0;i<e;i++){c=(c*m)%n;}for(i=0;i<d;i++){tmp=(tmp*c)%n;}printf("m:%d c:%d dec:%d\n",m,c,tmp);return 0;
}

代碼效果:

RSA-1024實現

涉及大數運算參考:https://editor.csdn.net/md/?articleId=109395413

#include<stdio.h> 
#include<stdlib.h>
#include<string.h>
#define max(a,b) (a>b?a:b)
#define BUFLEN 514int a[BUFLEN],b[BUFLEN],c[BUFLEN];//將數組設置為0 
int setZero(int*num,int len){memset(num,0,sizeof(int)*len);
}void hex_str2hex(char*str,int*num){setZero(num,BUFLEN);int i,j;int len=strlen(str);for(i=0;i<len;i++){if(str[len-1-i]<58&&str[len-1-i]>47) //0-9num[i]=str[len-1-i]-48;else if(str[len-1-i]<71&&str[len-1-i]>64) //A-Fnum[i]=10+str[len-1-i]-65;else if(str[len-1-i]<103&&str[len-1-i]>96) //a-fnum[i]=10+str[len-1-i]-97;}
}void hex2hex_str(int*num,char*str){int i,tmp;memset(str,0,BUFLEN);for(i=BUFLEN-1;num[i]==0;i--);//這里還能優化for(tmp=0;i>=0;i--,tmp++){if(num[i]>=0&&num[i]<=9)str[tmp]=num[i]+'0';else str[tmp]=num[i]-10+'A';}
}void str2hex_str(char*str1,char*str2){setZero(a,BUFLEN); int i,j,len=strlen(str1);for(i=0,j=2*len-1;i<len;i++){		a[j--]=(str1[i]>>4)&0xf;a[j--]=str1[i]&0xf;}hex2hex_str(a,str2);
}void hex_str2str(char*str1,char*str2){int i,len=strlen(str1);hex_str2hex(str1,a);memset(str2,0,BUFLEN);for(i=0;i<strlen(str1)/2;i++){str2[i]=(a[len-1-2*i]<<4)+a[len-2-2*i];}
}int compare(int*num1,int len1,int*num2,int len2){int i=len1-1,j=len2-1;if(i<j)return -1;else if(i>j)return 1;else{for(;i>=0;i--){if(num1[i]>num2[i])return 1;else if(num1[i]<num2[i])return -1;}return 0;}
}int copy(int*num1,int*num2,int len){int j;setZero(num1,BUFLEN);for(j=0;j<len;j++)num1[j]=num2[j];return len;
}//無符號大數加法 ,16進制 
void add(char*str1,char*str2,char*str3){		int i,carry=0;int len1=strlen(str1),len2=strlen(str2),len=max(len1,len2);hex_str2hex(str1,a);hex_str2hex(str2,b);setZero(c,BUFLEN);for(i=0;i<len;i++){c[i]=(a[i]+b[i]+carry)%16;carry=(a[i]+b[i]+carry)/16;}if(carry!=0)c[len++]=1;hex2hex_str(c,str3);
}//無符號大數減法,僅當str1大于str2時得到正確結果void sub(char*str1,char*str2,char*str3){int i,borrow=0;int len=strlen(str1);hex_str2hex(str1,a);hex_str2hex(str2,b);setZero(c,BUFLEN);for(i=0;i<len;i++){c[i]=a[i]-b[i]-borrow;if(c[i]<0&&i+1<len){borrow=1;c[i]+=16;}elseborrow=0;}hex2hex_str(c,str3);
}//帶符號大數加法,實際上沒用到這個函數 
void signAdd(char*str1,char*str2,char*str3){int len1=strlen(str1)-1,len2=strlen(str2)-1;hex_str2hex(&str1[1],a);hex_str2hex(&str2[1],b);if(str1[0]==str2[0]){add(&str1[1],&str2[1],&str3[1]);str3[0]=str1[0];}if(str1[0]!=str2[0]){if(compare(a,len1,b,len2)>0){sub(&str1[1],&str2[1],&str3[1]);str3[0]=str1[0];}else if(compare(a,len1,b,len2)<0){sub(&str2[1],&str1[1],&str3[1]);str3[0]=str2[0];}else{strcpy(str3,"+0");}}}//帶符號大數減法
void signSub(char*str1,char*str2,char*str3){int len1=strlen(str1)-1,len2=strlen(str2)-1;hex_str2hex(&str1[1],a);hex_str2hex(&str2[1],b);char tmp1=str1[0],tmp2=str2[0];memset(str3,0,BUFLEN);if(tmp1==tmp2){if(compare(a,len1,b,len2)>0){sub(&str1[1],&str2[1],&str3[1]);str3[0]=tmp1;}else if(compare(a,len1,b,len2)<0){sub(&str2[1],&str1[1],&str3[1]);if(tmp1=='+')str3[0]='-';else str3[0]='+';}else{strcpy(str3,"+0");}}if(tmp1!=tmp2){add(&str1[1],&str2[1],&str3[1]);str3[0]=tmp1;}
}//大數乘法 ,16進制 
void mul(char*str1,char*str2,char*str3) {	int i,j,k=0,carry=0,tmp; int len1=strlen(str1),len2=strlen(str2);hex_str2hex(str1,a);hex_str2hex(str2,b);setZero(c,BUFLEN);for(i=0;i<len1;i++){for(k=i,j=0;j<len2;j++,k++){c[k]+=a[i]*b[j];}}for(i=0;i<=k;i++) {c[i]+=carry;tmp=c[i];c[i]=tmp%16;carry=tmp/16;}hex2hex_str(c,str3);
}//大數除法,16進制 
void div(char*str1,char*str2,char*str3){	int i,j,tmp,tmp2=0,borrow=0,temp[BUFLEN]={0},temp2[BUFLEN]={0};int len1=strlen(str1),len2=strlen(str2);hex_str2hex(str1,a);hex_str2hex(str2,b);if(compare(a,len1,b,len2)<0){memset(str3,0,BUFLEN);return;}setZero(c,BUFLEN);while(compare(a,len1,b,len2)>=0){			tmp=len1-len2;if(tmp==tmp2&&tmp>0)tmp--;tmp2=tmp;setZero(temp2,BUFLEN);for(i=len1-1;i>=tmp;i--)temp2[i]=b[i-tmp];copy(temp,a,len1);if(compare(temp,len1,temp2,len2+tmp)<0)continue;for(j=1;;j++){borrow=0;for(i=tmp;i<len1;i++){temp[i]=a[i]-temp2[i]-borrow;if(temp[i]<0){borrow=1;temp[i]+=16;}elseborrow=0;}for(;temp[i]==0;i--);i++;len1=copy(a,temp,i);			c[tmp]=j;if(compare(temp,len1,temp2,len2+tmp)<0)break;}}hex2hex_str(c,str3);
}//大數模運算,16進制 
void mod(char*str1,char*str2,char*str3){setZero(c,BUFLEN);int i,j,tmp,tmp2=0,borrow=0,temp[BUFLEN]={0},temp2[BUFLEN]={0};int len1=strlen(str1),len2=strlen(str2);hex_str2hex(str1,a);hex_str2hex(str2,b);if(compare(a,len1,b,len2)<0){memset(str3,0,BUFLEN);hex2hex_str(a,str3);return;}while(compare(a,len1,b,len2)>=0){			tmp=len1-len2;if(tmp==tmp2&&tmp>0)tmp--;tmp2=tmp;setZero(temp2,BUFLEN);for(i=len1-1;i>=tmp;i--)temp2[i]=b[i-tmp];copy(temp,a,len1);if(compare(temp,len1,temp2,len2+tmp)<0)continue;for(j=1;;j++){borrow=0;for(i=tmp;i<len1;i++){temp[i]=a[i]-temp2[i]-borrow;if(temp[i]<0){borrow=1;temp[i]+=16;}elseborrow=0;}for(;temp[i]==0;i--);i++;len1=copy(a,temp,i);			c[tmp]=j;if(compare(temp,len1,temp2,len2+tmp)<0)break;}}hex2hex_str(temp,str3);
}int exgcd(char*str1,char*str2,char*x, char*y){if(strlen(str2)==0){strcpy(x,"+1");strcpy(y,"+0");return 1;}char temp[BUFLEN];mod(str1,str2,temp);int ret=exgcd(str2,temp,y,x);char temp2[BUFLEN+1]={0},temp3[BUFLEN+1]={0};div(str1,str2,temp2);mul(temp2,&x[1],&temp2[1]);temp2[0]=x[0];signSub(y,temp2,temp3);strcpy(y,temp3);return ret;
}//擴展歐幾里得求e的逆元d 
void genPrivateKey(char*e,char*fi,char*d){char x[BUFLEN+1]={0},y[BUFLEN+1]={0};int ret=exgcd(e,fi,x,y);if(x[0]=='+')add(&x[1],"",d);else if(x[0]=='-'){sub(fi,&x[1],d);mod(d,fi,d);}}#define HEX_ENC 0
#define HEX_DEC 1
#define STR_ENC 2
#define STR_DEC 3//利用反復平方乘加解密 
void enc_dec(char*str,char*key,char*n,char*out,int opt){char temp[BUFLEN]={0};int key_t[BUFLEN];if(opt==STR_ENC)str2hex_str(str,str);	strcpy(temp,"1");int i,tmp,flag;hex_str2hex(key,key_t);for(i=strlen(key)*4-1;((key_t[i/4]>>(i%4))&0x1)==0;i--);for(;i>=0;i--){mul(temp,temp,temp);mod(temp,n,temp);tmp=(key_t[i/4]>>(i%4))&0x1;if(tmp==1){mul(str,temp,temp);mod(temp,n,temp);}}if(opt==STR_DEC)hex_str2str(temp,out);else{strcpy(out,temp);}
}int  main(){char p[BUFLEN]="e86c7f16fd24818ffc502409d33a83c2a2a07fdfe971eb52de97a3de092980279ea29e32f378f5e6b7ab1049bb9e8c5eae84dbf2847eb94ff14c1e84cf568415";char q[BUFLEN]="d7d9d94071fcc67ede82084bbedeae1aaf765917b6877f3193bbaeb5f9f36007127c9aa98d436a80b3cce3fcd56d57c4103fb18f1819d5c238a49b0985fe7b49";char p1[BUFLEN],q1[BUFLEN],n[BUFLEN],fi[BUFLEN];sub(p,"1",p1);sub(q,"1",q1);mul(p,q,n);mul(p1,q1,fi); //計算獲得n和fi char e[BUFLEN]="100001",d[BUFLEN]; //存儲公私鑰,取e=65537較為合理 genPrivateKey(e,fi,d);//獲取解密鑰 char temp[BUFLEN];char M[BUFLEN]="b503be7137293906649e0ae436e29819ea2d06abf31e10091a7383349de84c5b",C[BUFLEN];//char M[BUFLEN]="this is a test",C[BUFLEN];printf("p: %s\n\nq: %s\n\nn: %s\n\nfi: %s\n\ne: %s\n\nd: %s\n\nM: %s\n\n",p,q,n,fi,e,d,M);enc_dec(M,e,n,C,HEX_ENC);printf("enc: %s\n\n",C);enc_dec(C,d,n,temp,HEX_DEC);printf("dec: %s\n\n",temp);	
}

加解密16進制字符串:

上述代碼在Dev C++, VS2010, gcc 中編譯均通過,一次完整的加解密時間大概在8秒左右,但是用python寫是真的快,1~2秒就完成了。

總結

以上是生活随笔為你收集整理的C语言实现RSA的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。