📄 rsa.cpp
字号:
#include <iostream>
#include <fstream>
#include <cstring>
#include<string>
#include "big.h" /* include MIRACL system */
#include "crt.h" /* chinese remainder thereom */
using namespace std;
#define NP 2 /* two primes - could be used with more */
Miracl precision=100;
static Big pd,pl,ph;
long randise()
{ /* get a random number 得到一个随机数*/
long seed;
cout << "Enter 9 digit random number seed = ";
cin >> seed;
return seed;
}
Big strongp(int n,long seed1,long seed2)
{ /* generate strong prime number =11 mod 12 suitable for RSA encryption */
Big p;
int r,r1,r2;
irand(seed1);
pd=rand(2*n/3,2);
pd=nextprime(pd);
ph=pow((Big)2,n-1)/pd;
pl=pow((Big)2,n-2)/pd;
ph-=pl;
irand(seed2);
ph=rand(ph);
ph+=pl;
r1=pd%12;
r2=ph%12;
r=0;
while ((r1*(r2+r))%12!=5) r++;
ph+=r;
do
{ /* find p=2*r*pd+1 = 11 mod 12 */
p=2*ph*pd+1;
ph+=12;
} while (!prime(p));
return p;
}
void strip(char * name)
{ /* strip off filename extension */
int i;
for (i=0;name[i]!='\0';i++)
{
if (name[i]!='.') continue;
name[i]='\0';
break;
}
}
void genkey()
{
int k,i;
//Miracl precision=100;
long seed[2*NP];
Big p[NP],ke;
ofstream public_key("public.txt");
ofstream private_key("private.txt");
miracl *mip=&precision;
gprime(15000); /* speeds up large prime generation */
do
{ cout << "size of each prime in bits= ";
cin >> k;
} while (k<128);
seed[0]=randise();
for (i=1;i<2*NP;i++)
seed[i]=seed[i-1]+2500;
cout << "generating keys - please wait\n";
ke=1;
for (i=0;i<NP;i++)
{
p[i]=strongp(k,seed[2*i],seed[2*i+1]);
ke*=p[i];
}
cout << "加密公钥\n";
cout << ke << endl;
cout << "解密私钥\n";
for (i=0;i<NP;i++)
cout << p[i] << endl;
mip->IOBASE=16;
public_key << ke << endl; //把公钥写到文件中去
for (i=0;i<NP;i++)
private_key << p[i] << endl; //把私钥写到文件中去
}
void encode()
{
Big e,m,y,ke,mn,mx;
ifstream public_key("public.key");
ifstream input_file;
ofstream output_file;
static char line[500];
static char buff[256];
static char ifname[13],ofname[13];
BOOL fli,last;
int i,ipt,klen;
miracl *mip=&precision;
mip->IOBASE=16;
public_key >> ke;
mn=root(ke,3);
mx=mn*mn*mn-mn*mn;
/* find key length in characters */
klen=bits(mx)/7;
cout << "file to be encoded = " ;
cin>>ifname;
// fli=FALSE;
//if (strlen(ifname)>0) fli=TRUE;
//if (fli)
// { // set up input file
strcpy(ofname,ifname);
strip(ofname);
strcat(ofname,".rsa");
input_file.open(ifname,ios::in);
/*if (!input_file)
{
cout << "Unable to open file " << ifname << "\n";
//return 0;
}*/
cout << "encoding message\n";
//}
/*else
{ // accept input from keyboard
cout << "output filename = ";
cin >> ofname;
strip(ofname);
strcat(ofname,".rsa");
cout << "input message - finish with cntrl z\n";
}*/
output_file.open(ofname);
ipt=0;
last=FALSE;
while (!last)
{ /* encode line by line */
if (fli)
{
input_file.getline(&line[ipt],132);
if (input_file.eof() || input_file.fail()) last=TRUE;
}
else
{
cin.getline(&line[ipt],132);
if (cin.eof() || cin.fail()) last=TRUE;
}
strcat(line,"\n");
ipt=strlen(line);
if (ipt<klen && !last) continue;
while (ipt>=klen)
{ /* chop up into klen-sized chunks and encode */
for (i=0;i<klen;i++)
buff[i]=line[i];
buff[klen]='\0';
for (i=klen;i<=ipt;i++)
line[i-klen]=line[i];
ipt-=klen;
mip->IOBASE=128;
m=buff;
e=pow(m,3,ke);
mip->IOBASE=16;
output_file << e << endl;
}
if (last && ipt>0)
{ /* now deal with left overs */
mip->IOBASE=128;
m=line;
if (m<mn)
{ /* pad out with random number if necessary */
m+=mn*(mn*mn-rand(mn));
}
e=pow(m,3,ke);
mip->IOBASE=16;
output_file << e << endl;
}
}
}
void decode()
{
int i;
//Miracl precision=100;
Big e,ep[NP],m,ke,p[NP],kp[NP],mn,mx;
ifstream private_key("private.key");
ifstream input_file;
ofstream output_file;
char ifname[13],ofname[13];
BOOL flo;
miracl *mip=&precision;
mip->IOBASE=16;
for (i=0;i<NP;i++)
{
private_key >> p[i];
}
/* construct public and private keys */
ke=1;
for (i=0;i<NP;i++)
{ /* Calculate ke */
ke*=p[i];
}
for (i=0;i<NP;i++)
{ /* prepare for Chinese remainder thereom *
* Find 1/3 mod p[i]-1 Euler TF */
kp[i]=(2*(p[i]-1)+1)/3;
}
mn=root(ke,3);
mx=mn*mn*mn-mn*mn;
do
{ /* get input file */
cout << "file to be decoded = ";
cin >> ifname;
} while (strlen(ifname)==0);
strip(ifname);
strcat(ifname,".rsa");
cout << "output filename = ";
cin.sync();
cin.getline(ofname,13);
flo=FALSE;
if (strlen(ofname)>0)
{ /* set up output file */
flo=TRUE;
output_file.open(ofname);
}
cout << "decoding message\n";
input_file.open(ifname,ios::in);
if (!input_file)
{
cout << "Unable to open file " << ifname << "\n";
}
Crt chinese(NP,p); /* use chinese remainder thereom */
forever
{ /* decode line by line */
mip->IOBASE=16;
input_file >> m;
if (m==0) break;
for (i=0;i<NP;i++)
ep[i]=pow(m,kp[i],p[i]);
e=chinese.eval(ep);
if (e>=mx) e%=mn;
mip->IOBASE=128;
if (flo) output_file << e;
cout << e << flush;
}
cout << "message ends\n";
}
void main()
{//mian()
cout<<"*******************欢迎使用本加密解密应用程序**********************"<<endl;
cout<<endl;
cout<<endl;
cout<<"*******************本应用程序利用的是RSA加密解密算法*************"<<endl;
cout<<"******************请输入一个数字进入菜单进行相关操作**************"<<endl;
cout<<"*********输入数字1:获取加密密钥和解密密钥"<<endl;
cout<<"*********输入数字2:对文件进行加密"<<endl;
cout<<"*********输入数字3:对文件进行解密"<<endl;
cout<<"*********输入数字4:推出本应用程序"<<endl;
int num;
cin>>num;
while(num)
{
if(num==1)
{ genkey();
cout<<"*********输入数字1:获取加密密钥和解密密钥"<<endl;
cout<<"*********输入数字2:对文件进行加密"<<endl;
cout<<"*********输入数字3:对文件进行解密"<<endl;
cout<<"*********输入数字4:推出本应用程序"<<endl;
cin>>num;
}
else if(num==2)
{
encode();
cout<<"*********输入数字1:获取加密密钥和解密密钥"<<endl;
cout<<"*********输入数字2:对文件进行加密"<<endl;
cout<<"*********输入数字3:对文件进行解密"<<endl;
cout<<"*********输入数字4:推出本应用程序"<<endl;
cin>>num;
}
else if(num==3)
{ decode();
cout<<"*********输入数字1:获取加密密钥和解密密钥"<<endl;
cout<<"*********输入数字2:对文件进行加密"<<endl;
cout<<"*********输入数字3:对文件进行解密"<<endl;
cout<<"*********输入数字4:推出本应用程序"<<endl;
cin>>num;
}
else if(num==4)
{ exit(0);}
// break;
}
//GENKEY
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -