在线rsa加解密算法(rsa算法解密过程)
大家好,如果您还对在线rsa加解密算法不太了解,没有关系,今天就由本站为大家分享在线rsa加解密算法的知识,包括rsa算法解密过程的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!
求正确的RSA加密解密算法C语言的,多谢。
//rsa.h
#include<stdio.h>
#defineMAX_NUM63001
#defineMAX_PRIME251
//!返回代码
#defineOK100
#defineERROR_NOEACHPRIME101
#defineERROR_NOPUBLICKEY102
#defineERROR_GENERROR103
unsignedintMakePrivatedKeyd(unsignedintuiP,unsignedintuiQ);
unsignedintGetPrivateKeyd(unsignedintiWhich);
unsignedintMakePairkey(unsignedintuiP,unsignedintuiQ,unsignedintuiD);
unsignedintGetPairKey(unsignedint&d,unsignedint&e);
voidrsa_encrypt(intn,inte,char*mw,intiLength,int*&cw);
voidrsa_decrypt(intn,intd,int*&cw,intcLength,char*mw);
voidoutputkey();
//rsa.c
#include"rsa.h"
//!保存私钥d**
structpKeyset
{
unsignedintset[MAX_NUM];
unsignedintsize;
}pset;
//!保存公、私钥对
structpPairkey
{
unsignedintd;
unsignedinte;
unsignedintn;
}pairkey;
//名称:isPrime
//功能:判断两个数是否互质
//粗兆参数:m:数a;n:数b
//返回:m、n互质返回true;否则返回false
boolisPrime(unsignedintm,unsignedintn)
{
unsignedinti=0;
boolFlag=true;
if(m<2||n<2)
returnfalse;
unsignedinttem=(m>n)?n:m;
for(i=2;i<=tem&&Flag;i++)
{
boolmFlag=true;
boolnFlag=true;
if(派哗m%i==0)
mFlag=false;
if(n%i==0)
nFlag=false;
if(!mFlag&&!nFlag)
Flag=false;
}
if(Flag)
returntrue;
else
returnfalse;
}
//名称:MakePrivatedKeyd
//功能:由素数Q、Q生成私钥d
//参数:uiP:素数P;uiQ:素数Q
//返回:私钥d
unsignedintMakePrivatedKeyd(unsignedintuiP,unsignedintuiQ)
{
unsignedinti=0;
//!得到所有与z互质的数(私钥d的**)
unsignedintz=(uiP-1)*(uiQ-1);
pset.size=0;
for(i=0;i<z;i++)
{
if(isPrime(i,z))
{
pset.set[pset.size++]=i;
}
}
returnpset.size;
}
//名称:MakePairKey
//功能:生成RSA公、私钥对
//参数:uiP:素数P;uiQ:素数Q;uiD:私钥d
//返回:错误代码
unsignedintMakePairkey(unsignedintuiP,unsignedintuiQ,unsignedintuiD)
{
boolbFlag=true;
unsignedinti=0,e;
unsignedintz=(uiP-1)*(uiQ-1);
unsigned尘凳行intd=pset.set[uiD];
//d=uiD;
if(!isPrime(z,d))
returnERROR_NOEACHPRIME;
for(i=2;i<z;i++)
{
if((i*d)%z==1)
{
e=i;
bFlag=false;
}
}
if(bFlag)
returnERROR_NOPUBLICKEY;
if((d*e)%z!=1)
ERROR_GENERROR;
pairkey.d=d;
pairkey.e=e;
pairkey.n=uiP*uiQ;
returnOK;
}
//名称:GetPairKey
//功能:对外提供接口,获得公、私钥对
//参数:uiP:素数P;uiQ:素数Q;uiD:私钥d
//返回:
unsignedintGetPairKey(unsignedint&d,unsignedint&e)
{
d=pairkey.d;
e=pairkey.e;
returnpairkey.n;
}
//名称:GetPrivateKeyd
//功能:对外提供接口,由用户选择ID得以私钥d
//参数:iWhich:用户选择私钥d的ID
//返回:私钥d值
unsignedintGetPrivateKeyd(unsignedintiWhich)
{
if(pset.size>=iWhich)
returnpset.set[iWhich];
else
return0;
}
//名称:rsa_encrypt
//功能:RSA加密运算
//参数:n:公钥n;e:公钥e;mw:加密明文;iLength:明文长度;cw:密文输出
//返回:无
voidrsa_encrypt(intn,inte,char*mw,intmLength,int*&cw)
{
inti=0,j=0;
__int64temInt=0;
for(i=0;i<mLength;i++)
{
temInt=mw[i];
if(e!=0)
{
for(j=1;j<e;j++)
{
temInt=(temInt*mw[i])%n;
}
}
else
{
temInt=1;
}
cw[i]=(int)temInt;
}
}
//名称:rsa_decrypt
//功能:RSA解密运算
//参数:n:私钥n;d:私钥d;cw:密文;cLength:密文长度;mw:明文输出
//返回:无
voidrsa_decrypt(intn,intd,int*&cw,intcLength,char*mw)
{
inti=0,j=-1;
__int64temInt=0;
for(i=0;i<cLength/4;++i)
{
mw[i]=0;
temInt=cw[i];
if(d!=0)
{
for(j=1;j<d;j++)
{
temInt=(__int64)(temInt*cw[i])%n;
}
}
else
{
temInt=1;
}
mw[i]=(char)temInt;
}
}
voidoutputkey()
{
printf("PublicKey(e,n):(%d,%d)\n",pairkey.e,pairkey.n);
printf("PrivateKey(d,n):(%d,%d)\n",pairkey.d,pairkey.n);
}
//main.c
//工程:RSA
//功能:RSA加、解密文件
//作者:jlcss|ExpNIS
#include<stdio.h>
#include<afxwin.h>
#include<math.h>
#include"rsa.h"
#defineDECRYPT_FILE"RSA加密密文.txt"
#defineENCRYPT_FILE"RSA解密明文.txt"
//!约束文件最大2M
#defineMAX_FILE1024*1024*2
//名称:usage
//功能:帮助信息
//参数:应用程序名称
//返回:提示信息
voidUsage(constchar*appname)
{
printf("\n\tusage:rsa-k素数P素数Q\n");
printf("\tusage:rsa-e明文文件公钥e公钥n\n");
printf("\tusage:rsa-d密文文件私钥d私钥n\n");
}
//名称:IsNumber
//功能:判断数字字符数组
//参数:strNumber:字符数组
//返回:数字字组数组返回true,否则返回false;
boolIsNumber(constchar*strNumber)
{
unsignedinti;
if(!strNumber)
returnfalse;
for(i=0;i<strlen(strNumber);i++)
{
if(strNumber[i]<'0'||strNumber[i]>'9')
returnfalse;
}
returntrue;
}
//名称:IsPrimeNumber
//功能:判断素数
//参数:num:输入整数
//返回:素数返回true,否则返回false;
boolIsPrimeNumber(unsignedintnum)
{
unsignedinti;
if(num<=1)
returnfalse;
unsignedintsqr=(unsignedint)sqrt((double)num);
for(i=2;i<=sqr;i++)
{
if(num%i==0)
returnfalse;
}
returntrue;
}
//名称:FileIn
//功能:读取磁盘文件到内存
//参数:strFile:文件名称;inBuff:指向文件内容缓冲区
//返回:实际读取内容大小(字节)
intFileIn(constchar*strFile,unsignedchar*&inBuff)
{
intiFileLen=0,iBuffLen=0;
//!打开密文文件
CFilefile(strFile,CFile::modeRead);
iFileLen=(int)file.GetLength();
if(iFileLen>MAX_FILE)
{
printf("文件长度不能大于%dM,!\n",MAX_FILE/(1024*1024));
gotoout;
}
iBuffLen=iFileLen;
inBuff=newunsignedchar[iBuffLen];
if(!inBuff)
gotoout;
ZeroMemory(inBuff,iBuffLen);
file.Read(inBuff,iFileLen);
file.Close();
out:
returniBuffLen;
}
//名称:FileOut
//功能:加/解密结果输出到当前目录磁盘文件中
//参数:strOut指向输出字符缓冲区,输出大小len,strFile为输出文件
//返回:无
voidFileOut(constvoid*strOut,intlen,constchar*strFile)
{
//!输出到文件
CFileoutfile(strFile,CFile::modeCreate|CFile::modeWrite);
outfile.Write(strOut,len);
outfile.Close();
}
//名称:CheckParse
//功能:校验应用程序入口参数
//参数:argc等于main主函数argc参数,argv指向main主函数argv参数
//返回:若参数合法返回true,否则返回false
//备注:简单的入口参数校验
boolCheckParse(intargc,char**argv)
{
boolbRes=false;
if(argc!=4&&argc!=5)
gotoout;
if(argc==4&&argv[1][1]=='k')
{
//!生成公、私钥对
if(!IsNumber(argv[2])||
!IsNumber(argv[3])||
atoi(argv[2])>MAX_PRIME||
atoi(argv[3])>MAX_PRIME)
gotoout;
}
elseif((argc==5)&&(argv[1][1]=='e'||argv[1][1]=='d'))
{
//!加密、解密操作
if(!IsNumber(argv[3])||
!IsNumber(argv[4])||
atoi(argv[3])>MAX_NUM||
atoi(argv[4])>MAX_NUM)
gotoout;
}
else
Usage(*argv);
bRes=true;
out:
returnbRes;
}
//名称:kOption1
//功能:程序k选项操作:由素数P、Q生成私钥d**
//参数:uiP:程序入口参数P;uiQ:程序入口参数Q
//返回:执行正确返回生成私钥数目,否则返回0
unsignedintkOption1(unsignedintuiP,unsignedintuiQ)
{
unsignedintuiRes=0;
if(!IsPrimeNumber(uiP))
{
printf("P输入错误,P必须为(0,%d]素数",MAX_PRIME);
returnuiRes;
}
if(!IsPrimeNumber(uiQ))
{
printf("Q输入错误,Q必须为(0,%d]素数",MAX_PRIME);
returnuiRes;
}
if(uiP==uiQ)
{
printf("素数P与素数Q相同,很容易根据公钥n开平方得出素数P和Q,这种加密不安全,请更换素数!\n");
returnuiRes;
}
printf("正在生成私钥d**......\n");
uiRes=MakePrivatedKeyd(uiP,uiQ);
returnuiRes;
}
//!程序主函数
intmain(intargc,char**argv)
{
unsignedintp,q,d,n,e;//twoprimep&q,publickey(n,e),privatekey(n,d)
CheckParse(argc,argv);
d=4828;//uid
if(argc==4)
{
p=atoi(argv[2]);
q=atoi(argv[3]);
MakePrivatedKeyd(p,q);
MakePairkey(p,q,d);
outputkey();
}
elseif(argc==5)
{
charFileName[20];
strcpy(FileName,argv[2]);
intlen;
if(argv[1][1]=='e')
{
unsignedchar*inBuffer=(unsignedchar*)malloc(MAX_FILE);//输入缓冲区
int*cw=(int*)malloc(MAX_FILE);
len=FileIn(FileName,inBuffer);
e=atoi(argv[3]);
n=atoi(argv[4]);
rsa_encrypt(n,e,(char*)inBuffer,len,cw);
FileOut(cw,4*len,DECRYPT_FILE);
}
elseif(argv[1][1]=='d')
{
char*Buffer=(char*)malloc(MAX_FILE);//输入缓冲区
int*cw=(int*)malloc(MAX_FILE);
len=FileIn(FileName,(unsignedchar*&)cw);
d=atoi(argv[3]);
n=atoi(argv[4]);
rsa_decrypt(n,d,cw,len,Buffer);
FileOut(Buffer,len/4,ENCRYPT_FILE);
}
}
return0;
}
高分求java的RSA 和IDEA 加密解密算法
RSA算法非常简单,概述如下:
找两素数p和q
取n=p*q
取t=(p-1)*(q-1)
取任何一个数e,要求满足e<t并且e与t互素(就是最大公因数为1)
取d*e%t==1
这样最终得到三个数: n d e
设消息为数M(M<n)
设c=(M**d)%n就得到了加密后的消息c
设m=(c**e)%n则 m== M,从而完成对c的解密。
注:**表示次方,上面两式中的d和e可以互换。
在对称加密中:
n d两个数构成公钥,可以告诉别人;
n e两个数构成私钥,e自己保留,不让任何人知道。
给别人发送的信息使用e加密,只要别人能用d解开就证明信息是由你发送的,构成了签名机制。
别人给你发送信息时使竖帆用d加密,这样只有拥有e的你能够对其解密。
rsa的安全性在于对于一个大数n,没有有效的方法能够将其分解
从而在已知n d的情况下无法获得e;同样在已知n e的情况漏凳下无法
求得d。
<二>实践
接下来我们来一个实践,看看实际的操作:
找两个素数:
p=47
q=59
这样
n=p*q=2773
t=(p-1)*(q-1)=2668
取e=63,满足e<t并且e和t互素
用perl简单穷举可以获得满主 e*d%t==1的数d:
C:\Temp>perl-e"foreach$i(1..9999){ print($i),last if$i*63%2668==1}"
847
即d=847
最终我们获得关键的
n=2773
d=847
e=63
取消息M=244我们看看
加密:
c=M**d%n= 244**847%2773
用perl的大数计算来算一下:
C:\Temp>perl-Mbigint-e"print 244**847%2773"
465
即用d对M加密后获得加密信息c=465
解密:
我们可以用e来对加密后的c进行解密,还原M:
m=c**e%n=465**63%2773:
C:\Temp>perl-Mbigint-e"print 465**63%2773"
244
即用e对c解密后获得m=244,该值和原始信息M相等。
<三>字符串加密
把上面的过程集成一下我们就能实现一个对字符串加密解密的示例了。余搜雹
每次取字符串中的一个字符的ascii值作为M进行计算,其输出为加密后16进制
的数的字符串形式,按3字节表示,如01F
代码如下:
#!/usr/bin/perl-w
#RSA计算过程学习程序编写的测试程序
#watercloud 2003-8-12
#
use strict;
use Math::BigInt;
my%RSA_CORE=(n=>2773,e=>63,d=>847);#p=47,q=59
my$N=new Math::BigInt($RSA_CORE{n});
my$E=new Math::BigInt($RSA_CORE{e});
my$D=new Math::BigInt($RSA_CORE{d});
print"N=$N D=$D E=$E\n";
sub RSA_ENCRYPT
{
my$r_mess= shift@_;
my($c,$i,$M,$C,$cmess);
for($i=0;$i< length($$r_mess);$i++)
{
$c=ord(substr($$r_mess,$i,1));
$M=Math::BigInt->new($c);
$C=$M->copy();$C->bmodpow($D,$N);
$c=sprintf"%03X",$C;
$cmess.=$c;
}
return\$cmess;
}
sub RSA_DECRYPT
{
my$r_mess= shift@_;
my($c,$i,$M,$C,$dmess);
for($i=0;$i< length($$r_mess);$i+=3)
{
$c=substr($$r_mess,$i,3);
$c=hex($c);
$M=Math::BigInt->new($c);
$C=$M->copy();$C->bmodpow($E,$N);
$c=chr($C);
$dmess.=$c;
}
return\$dmess;
}
my$mess="RSA娃哈哈哈~~~";
$mess=$ARGV[0] if@ARGV>= 1;
print"原始串:",$mess,"\n";
my$r_cmess= RSA_ENCRYPT(\$mess);
print"加密串:",$$r_cmess,"\n";
my$r_dmess= RSA_DECRYPT($r_cmess);
print"解密串:",$$r_dmess,"\n";
#EOF
测试一下:
C:\Temp>perl rsa-test.pl
N=2773 D=847 E=63
原始串:RSA娃哈哈哈~~~
加密串:5CB6CD6BC58A7709470AA74A0AA74A0AA74A6C70A46C70A46C70A4
解密串:RSA娃哈哈哈~~~
C:\Temp>perl rsa-test.pl安全焦点(xfocus)
N=2773 D=847 E=63
原始串:安全焦点(xfocus)
加密串:3393EC12F0A466E0AA9510D025D7BA0712DC3379F47D51C325D67B
解密串:安全焦点(xfocus)
<四>提高
前面已经提到,rsa的安全来源于n足够大,我们测试中使用的n是非常小的,根本不能保障安全性,
我们可以通过RSAKit、RSATool之类的工具获得足够大的N及D E。
通过工具,我们获得1024位的N及D E来测试一下:
n=0x328C74784DF31119C526D18098EBEBB943B0032B599CEE13CC2BCE7B5FCD15F90B66EC3A85F5005D
BDCDED9BDFCB3C4C265AF164AD55884D8278F791C7A6BFDAD55EDBC4F017F9CCF1538D4C2013433B383B
47D80EC74B51276CA05B5D6346B9EE5AD2D7BE7ABFB36E37108DD60438941D2ED173CCA50E114705D7E2
BC511951
d=0x10001
e=0xE760A3804ACDE1E8E3D7DC0197F9CEF6282EF552E8CEBBB7434B01CB19A9D87A3106DD28C523C2995
4C5D86B36E943080E4919CA8CE08718C3B0930867A98F635EB9EA9200B25906D91B80A47B77324E66AFF2
C4D70D8B1C69C50A9D8B4B7A3C9EE05FFF3A16AFC023731D80634763DA1DCABE9861A4789BD782A592D2B
1965
设原始信息
M=0x11111111111122222222222233333333333
完成这么大数字的计算依赖于大数运算库,用perl来运算非常简单:
A)用d对M进行加密如下:
c=M**d%n:
C:\Temp>perl-Mbigint-e"$x=Math::BigInt->bmodpow(0x11111111111122222222222233
333333333, 0x10001, 0x328C74784DF31119C526D18098EBEBB943B0032B599CEE13CC2BCE7B5F
CD15F90B66EC3A85F5005DBDCDED9BDFCB3C4C265AF164AD55884D8278F791C7A6BFDAD55EDBC4F0
17F9CCF1538D4C2013433B383B47D80EC74B51276CA05B5D6346B9EE5AD2D7BE7ABFB36E37108DD6
0438941D2ED173CCA50E114705D7E2BC511951);print$x->as_hex"
0x17b287be418c69ecd7c39227ab681ac422fcc84bb35d8a632543b304de288a8d4434b73d2576bd
45692b007f3a2f7c5f5aa1d99ef3866af26a8e876712ed1d4cc4b293e26bc0a1dc67e247715caa6b
3028f9461a3b1533ec0cb476441465f10d8ad47452a12db0601c5e8beda686dd96d2acd59ea89b91
f1834580c3f6d90898
即用d对M加密后信息为:
c=0x17b287be418c69ecd7c39227ab681ac422fcc84bb35d8a632543b304de288a8d4434b73d2576bd
45692b007f3a2f7c5f5aa1d99ef3866af26a8e876712ed1d4cc4b293e26bc0a1dc67e247715caa6b
3028f9461a3b1533ec0cb476441465f10d8ad47452a12db0601c5e8beda686dd96d2acd59ea89b91
f1834580c3f6d90898
B)用e对c进行解密如下:
m=c**e%n:
C:\Temp>perl-Mbigint-e"$x=Math::BigInt->bmodpow(0x17b287be418c69ecd7c39227ab
681ac422fcc84bb35d8a632543b304de288a8d4434b73d2576bd45692b007f3a2f7c5f5aa1d99ef3
866af26a8e876712ed1d4cc4b293e26bc0a1dc67e247715caa6b3028f9461a3b1533ec0cb4764414
65f10d8ad47452a12db0601c5e8beda686dd96d2acd59ea89b91f1834580c3f6d90898, 0xE760A
3804ACDE1E8E3D7DC0197F9CEF6282EF552E8CEBBB7434B01CB19A9D87A3106DD28C523C29954C5D
86B36E943080E4919CA8CE08718C3B0930867A98F635EB9EA9200B25906D91B80A47B77324E66AFF
2C4D70D8B1C69C50A9D8B4B7A3C9EE05FFF3A16AFC023731D80634763DA1DCABE9861A4789BD782A
592D2B1965, 0x328C74784DF31119C526D18098EBEBB943B0032B599CEE13CC2BCE7B5FCD15F90
B66EC3A85F5005DBDCDED9BDFCB3C4C265AF164AD55884D8278F791C7A6BFDAD55EDBC4F017F9CCF
1538D4C2013433B383B47D80EC74B51276CA05B5D6346B9EE5AD2D7BE7ABFB36E37108DD60438941
D2ED173CCA50E114705D7E2BC511951);print$x->as_hex"
0x11111111111122222222222233333333333
(我的P4 1.6G的机器上计算了约5秒钟)
得到用e解密后的m=0x11111111111122222222222233333333333== M
C) RSA通常的实现
RSA简洁幽雅,但计算速度比较慢,通常加密中并不是直接使用RSA来对所有的信息进行加密,
最常见的情况是随机产生一个对称加密的密钥,然后使用对称加密算法对信息加密,之后用
RSA对刚才的加密密钥进行加密。
最后需要说明的是,当前小于1024位的N已经被证明是不安全的
自己使用中不要使用小于1024位的RSA,最好使用2048位的。
----------------------------------------------------------
一个简单的RSA算法实现JAVA源代码:
filename:RSA.java
/*
* Created on Mar 3, 2005
*
* TODO To change the template for this generated file go to
* Window- Preferences- Java- Code Style- Code Templates
*/
import java.math.BigInteger;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.BufferedReader;
import java.util.StringTokenizer;

/**
*@author Steve
*
* TODO To change the template for this generated type comment go to
* Window- Preferences- Java- Code Style- Code Templates
*/
public class RSA{
/**
* BigInteger.ZERO
*/
private static final BigInteger ZERO= BigInteger.ZERO;
/**
* BigInteger.ONE
*/
private static final BigInteger ONE= BigInteger.ONE;
/**
* Pseudo BigInteger.TWO
*/
private static final BigInteger TWO= new BigInteger("2");
private BigInteger myKey;
private BigInteger myMod;
private int blockSize;
public RSA(BigInteger key, BigInteger n, int b){
myKey= key;
myMod= n;
blockSize= b;
}
public void encodeFile(String filename){
byte[] bytes= new byte[blockSize/ 8+ 1];
byte[] temp;
int tempLen;
InputStream is= null;
FileWriter writer= null;
try{
is= new FileInputStream(filename);
writer= new FileWriter(filename+".enc");
}
catch(FileNotFoundException e1){
System.out.println("File not found:"+ filename);
}
catch(IOException e1){
System.out.println("File not found:"+ filename+".enc");
}
/**
* Write encoded message to'filename'.enc
*/
try{
while((tempLen= is.read(bytes, 1, blockSize/ 8))> 0){
for(int i= tempLen+ 1; i< bytes.length;++i){
bytes[i]= 0;
}
writer.write(encodeDecode(new BigInteger(bytes))+"");
}
}
catch(IOException e1){
System.out.println("error writing to file");
}
/**
* Close input stream and file writer
*/
try{
is.close();
writer.close();
}
catch(IOException e1){
System.out.println("Error closing file.");
}
}
public void decodeFile(String filename){
FileReader reader= null;
OutputStream os= null;
try{
reader= new FileReader(filename);
os= new FileOutputStream(filename.replaceAll(".enc",".dec"));
}
catch(FileNotFoundException e1){
if(reader== null)
System.out.println("File not found:"+ filename);
else
System.out.println("File not found:"+ filename.replaceAll(".enc","dec"));
}
BufferedReader br= new BufferedReader(reader);
int offset;
byte[] temp, toFile;
StringTokenizer st= null;
try{
while(br.ready()){
st= new StringTokenizer(br.readLine());
while(st.ha*oreTokens()){
toFile= encodeDecode(new BigInteger(st.nextToken())).toByteArray();
System.out.println(toFile.length+" x"+(blockSize/ 8));
if(toFile[0]== 0&& toFile.length!=(blockSize/ 8)){
temp= new byte[blockSize/ 8];
offset= temp.length- toFile.length;
for(int i= toFile.length- 1;(i<= 0)&&((i+ offset)<= 0);--i){
temp[i+ offset]= toFile[i];
}
toFile= temp;
}
/*if(toFile.length!=((blockSize/ 8)+ 1)){
temp= new byte[(blockSize/ 8)+ 1];
System.out.println(toFile.length+" x"+ temp.length);
for(int i= 1; i< temp.length; i++){
temp[i]= toFile[i- 1];
}
toFile= temp;
}
else
System.out.println(toFile.length+""+((blockSize/ 8)+ 1));*/
os.write(toFile);
}
}
}
catch(IOException e1){
System.out.println("Something went wrong");
}
/**
* close data streams
*/
try{
os.close();
reader.close();
}
catch(IOException e1){
System.out.println("Error closing file.");
}
}
/**
* Performs<tt>base</tt>^<sup><tt>pow</tt></sup> within the modular
* domain of<tt>mod</tt>.
*
*@param base the base to be raised
*@param pow the power to which the base will be raisded
*@param mod the modular domain over which to perform this operation
*@return<tt>base</tt>^<sup><tt>pow</tt></sup> within the modular
* domain of<tt>mod</tt>.
*/
public BigInteger encodeDecode(BigInteger base){
BigInteger a= ONE;
BigInteger s= base;
BigInteger n= myKey;
while(!n.equals(ZERO)){
if(!n.mod(TWO).equals(ZERO))
a= a.multiply(s).mod(myMod);
s= s.pow(2).mod(myMod);
n= n.divide(TWO);
}
return a;
}
}
在这里提供两个版本的RSA算法JAVA实现的代码下载:
1.来自于 http://www.javafr.com/code.aspx?ID=27020的RSA算法实现源代码包:
http://zeal.newmenbase.net/attachment/JavaFR_RSA_Source.rar
2.来自于 http://www.ferrara.linux.it/Members/lucabariani/RSA/implementazioneRsa/的实现:
http://zeal.newmenbase.net/attachment/sorgentiJava.tar.gz-源代码包
http://zeal.newmenbase.net/attachment/algoritmoRSA.jar-编译好的jar包
另外关于RSA算法的php实现请参见文章:
php下的RSA算法实现
关于使用VB实现RSA算法的源代码下载(此程序采用了psc1算法来实现快速的RSA加密):
http://zeal.newmenbase.net/attachment/vb_PSC1_RSA.rar
RSA加密的JavaScript实现: http://www.ohdave.com/rsa/
求RSA加密解密算法,c++源代码
//下面程序由520huiqin编写,已在VC++ 6.0下编译通过
#include<iostream.h>
#include<math.h>
#include<stdio.h>
typedef int Elemtype;
Elemtype p,q,e;
Elemtype fn;
Elemtype m,c;
int flag= 0;
typedef void(*Msghandler)(void);
struct MsgMap{
char ch;
Msghandler handler;
};
/*公钥*/
struct PU{
Elemtype e;
Elemtype n;
} pu;
/*私钥*/
struct PR{
Elemtype d;
Elemtype n;
} pr;
/*判定一个数是否为素数*/
bool test_prime(Elemtype m){
if(m<= 1){
return false;
}
else if(m== 2){
return true;
}
else{
for(int i=2; i<=sqrt(m); i++){
if((m% i)== 0){
return false;
break;
}
}
return true;
}
}
/*将十进制数据转化为二进制数历局组*/
void switch_to_bit(Elemtype b, Elemtype bin[32]){
int n= 0;
while( b> 0){
bin[n]= b% 2;
n++;
b/= 2;
}
}
/*候选菜单,主界面*/
void Init(){
cout<<"*********************************************"<<endl;
cout<<"*** Welcome to use RSA encoder***"<袭烂闹<endl;
cout<<"*** a.about***"拍罩<<endl;
cout<<"*** e.encrypt***"<<endl;
cout<<"*** d.decrypt***"<<endl;
cout<<"*** s.setkey***"<<endl;
cout<<"*** q.quit***"<<endl;
cout<<"**********************************by*Terry***"<<endl;
cout<<"press a key:"<<endl;
}
/*将两个数排序,大的在前面*/
void order(Elemtype&in1, Elemtype&in2){
Elemtype a=( in1> in2? in1: in2);
Elemtype b=( in1< in2? in1: in2);
in1= a;
in2= b;
}
/*求最大公约数*/
Elemtype gcd(Elemtype a, Elemtype b){
order(a,b);
int r;
if(b== 0){
return a;
}
else{
while(true){
r= a% b;
a= b;
b= r;
if(b== 0){
return a;
break;
}
}
}
}
/*用扩展的欧几里得算法求乘法逆元*/
Elemtype extend_euclid(Elemtype m, Elemtype bin){
order(m,bin);
Elemtype a[3],b[3],t[3];
a[0]= 1, a[1]= 0, a[2]= m;
b[0]= 0, b[1]= 1, b[2]= bin;
if(b[2]== 0){
return a[2]= gcd(m, bin);
}
if(b[2]==1){
return b[2]= gcd(m, bin);
}
while(true){
if(b[2]==1){
return b[1];
break;
}
int q= a[2]/ b[2];
for(int i=0; i<3; i++){
t[i]= a[i]- q* b[i];
a[i]= b[i];
b[i]= t[i];
}
}
}
/*快速模幂算法*/
Elemtype modular_multiplication(Elemtype a, Elemtype b, Elemtype n){
Elemtype f= 1;
Elemtype bin[32];
switch_to_bit(b,bin);
for(int i=31; i>=0; i--){
f=(f* f)% n;
if(bin[i]== 1){
f=(f* a)% n;
}
}
return f;
}
/*产生密钥*/
void produce_key(){
cout<<"input two primes p and q:";
cin>>p>>q;
while(!(test_prime(p)&&test_prime(q))){
cout<<"wrong input,please make sure two number are both primes!"<<endl;
cout<<"input two primes p and q:";
cin>>p>>q;
};
pr.n= p* q;
pu.n= p* q;
fn=(p- 1)*(q- 1);
cout<<"fn="<<fn<<endl;
cout<<"input e:";
cin>>e;
while((gcd(fn,e)!=1)){
cout<<"e is error,try again!";
cout<<"input e:";
cin>>e;
}
pr.d=(extend_euclid(fn,e)+ fn)% fn;
pu.e= e;
flag= 1;
cout<<"PR.d:"<<pr.d<<" PR.n:"<<pr.n<<endl;
cout<<"PU.e:"<<pu.e<<" PU.n:"<<pu.n<<endl;
}
/*加密*/
void encrypt(){
if(flag== 0){
cout<<"setkey first:"<<endl;
produce_key();
}
cout<<"input m:";
cin>>m;
c= modular_multiplication(m,pu.e,pu.n);
cout<<"c is:"<<c<<endl;
}
/*解密*/
void decrypt(){
if(flag== 0){
cout<<"setkey first:"<<endl;
produce_key();
}
cout<<"input c:";
cin>>c;
m= modular_multiplication(c,pr.d,pr.n);
cout<<"m is:"<<m<<endl;
}
/*版权信息*/
void about(){
cout<<"*********************************************"<<endl;
cout<<"*** by Terry***"<<endl;
cout<<"*** copyright 2010,All rights reserved by***"<<endl;
cout<<"*** Terry,technology supported by weizuo!***"<<endl;
cout<<"*** If you have any question, please mail***"<<endl;
cout<<"*** to 18679376@qq.com!***"<<endl;
cout<<"*** Computer of science and engineering***"<<endl;
cout<<"*** XiDian University 2010-4-29***"<<endl;
cout<<"*********************************************"<<endl;
cout<<endl<<endl;
Init();
}
/*消息映射*/
MsgMap Messagemap[]={
{'a',about},
{'s',produce_key},
{'d',decrypt},
{'e',encrypt},
{'q',NULL}
};
/*主函数,提供循环*/
void main(){
Init();
char d;
while((d= getchar())!='q'){
int i= 0;
while(Messagemap[i].ch){
if(Messagemap[i].ch== d){
Messagemap[i].handler();
break;
}
i++;
}
}
}
//欢迎分享,盗窃可耻
rsa加密解密算法
1978年就出现了这种算法,它是第一个既能用于数据加密
也能用于数字签名的算法。它易于理解和操作,也锋碧很流行。算
法的名字以发明者的名字命名:Ron Rivest, AdiShamir和
Leonard Adleman。但RSA的安全性一直未能得到理论上的证明。
RSA的安全性依赖于大数分解。公钥和私钥都是两个大素数
(大于 100个十进制位)的函数。据猜测,从一个密钥和密文
推断出明文的难度等同于分解两个大素数的积。
密钥对的产生:选择两个大素数,p和q。计算:
n= p* q
然后随机选择加密密钥e,要求 e和( p- 1)*( q- 1)
互质。最后,利用Euclid算法计算解密密钥d,满足
e* d= 1( mod( p- 1)*( q- 1))
其中n和d也要互质。数e和
n是公钥,d是私钥。两个素数p和q不再需要,应该丢弃,不要让任
何人知道。加密信息 m(二进制表示)时,首先把m分成等长数据
块 m1,m2,..., mi,块长s,其中 2^s<= n, s尽可能的大。对
应的密文是:
ci= mi^e( mod n)( a)
解密时作如下计算:
mi= ci^d( mod n)( b)
RSA可用于数字签名,方案是用( a)式签名,( b)
式验证。具体操作时考虑到安全性和 m信息量较大等因素,一般是先
作 HASH运算。
RSA的安全性。
RSA的安全性依赖于大数分解,但是否等同于大数分解一直未能得到理
论上的证明,因为没有证明破解RSA就一定需要作大数分解。假设存在
一种无须分解大数的算法,那它肯定可以修改成为大数分解算法。目前,
RSA的一些变种算法已被证明等价于大数分解。不管怎样,分解n是最显
然的银茄举攻击方法。现在,人们已能分解140多个十进制位的大素数。因此,
模数n必须选大一些,因具体适用情况而定。
RSA的速度:
由于进行的都是大数计算,使得RSA最快的情况也比DES慢上100倍,无论
是软件还是硬件实现。速度一直是RSA的缺陷。一般来说只用于少量数据
加密。
RSA的选择密文攻击:
RSA在选择密文攻击面前很脆弱。一般攻击者是将某一信息作一下伪装
(Blind),让拥有私钥的实体签署。然后,经过计算就可得到它所想要的信
息。实际上,攻击利用的都是同一个弱点,即存在这样一个事实:乘幂保
留了输入的乘法结构:
( XM)^d= X^d*M^d mod n
前面已经提到,这个固有的问题来自于公钥密码系统的最有用的特征
--每个人都能使用公钥。但从算法上无法解决这一问题,主要措施有
两条:一条是采用好的公钥协议,保证工作过程中实体不对其他实体
任意产生的信息解密,不对自己一无所知的信息签名;另一条是决不
对陌生人送来的随机文档签名,签名时首先使用One-Way HashFunction
对文档作HASH处理,或同纳游时使用不同的签名算法。在中提到了几种不
同类型的攻击方法。
RSA的公共模数攻击。
若系统中共有一个模数,只是不同的人拥有不同的e和d,系统将是危险
的。最普遍的情况是同一信息用不同的公钥加密,这些公钥共模而且互
质,那末该信息无需私钥就可得到恢复。设P为信息明文,两个加密密钥
为e1和e2,公共模数是n,则:
C1= P^e1 mod n
C2= P^e2 mod n
密码分析者知道n、e1、e2、C1和C2,就能得到P。
因为e1和e2互质,故用Euclidean算法能找到r和s,满足:
r* e1+ s* e2= 1
假设r为负数,需再用Euclidean算法计算C1^(-1),则
( C1^(-1))^(-r)* C2^s= P mod n
另外,还有其它几种利用公共模数攻击的方法。总之,如果知道给定模数
的一对e和d,一是有利于攻击者分解模数,一是有利于攻击者计算出其它
成对的e’和d’,而无需分解模数。解决办法只有一个,那就是不要共享
模数n。
RSA的小指数攻击。有一种提高
RSA速度的建议是使公钥e取较小的值,这样会使加密变得易于实现,速度
有所提高。但这样作是不安全的,对付办法就是e和d都取较大的值。
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。
RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各
种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。
RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难
度与大数分解难度等价。即RSA的重大缺陷是无法从理论上把握它的保密性
能如何,而且密码学界多数人士倾向于因子分解不是NPC问题。
RSA的缺点主要有:
A)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次
一密。B)分组长度太大,为保证安全性,n至少也要 600 bits
以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;
且随着大数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。
目前,SET(Secure Electronic Transaction)协议中要求CA采用2048比特长
的密钥,其他实体使用1024比特的密钥。
RSA加密解密算法示例(C语言)
#include<stdlib.h>
#include<stdio.h>
#include<没消string.h>
#include<math.h>
#include<time.h>
#define PRIME_MAX 200 //生成素数范围
#define EXPONENT_MAX 200//生成指数e范围
#define Element_Max 127 //加密单元的最大值,这里为一个char,即1Byte
char str_read[100]="hello world!"; //待加密的原文
int str_encrypt[100]; //加密后的内容
char str_decrypt[100]; //解密出来的内容
int str_read_len; // str_read的长度
int prime1, prime2; //随机生成的两个质数
int mod, eular; //模数和欧拉数
int pubKey, priKey; //公钥指数和私钥指数
//生成随机素数,实际应用中,这两个质数越大,就越难破解。
int randPrime()
{
int prime, prime2, i;
next:
prime= rand()% PRIME_MAX; //随机产生数
if(prime<= 1) goto next; //不是质数,生成下一个随机数
if(prime== 2|| prime== 3) return prime;
prime2= prime/ 2; // prime>=4, prime2的平方必定大于 prime,因此只检查银察厅小于等于prime2的数
for(i= 2; i<= prime2; i++) //判断是否为素数
{
if(i* i> prime) return prime;
if(prime% i== 0) goto next; //不是质数,生成下一个随机数
}
}
//欧几里德算法,判断a,b互质
int gcd(int a, int b)
{
int temp;
while(b!= 0){
temp= b;
b= a% b;
a= temp;
}
return a;
}
//生成公钥指数,条件是 1< e<欧拉数,且与欧拉数互质。
int randExponent()
{
int e;
while(1)
{
e= rand()% eular; if(e< EXPONENT_MAX) break;
}
while(1)
{
if(gcd(e, eular)== 1) return e; e=(e+ 1)% eular; if(e== 0|| e> EXPONENT_MAX) e= 2;
}
}
//生成私钥指数
int inverse()
{
int d, x;
while(1)
{
d= rand()% eular;
x= pubKey* d% eular;
if(x== 1)
{
return d;
}
}
}
//加密函数
void jiami()
{
str_read_len= strlen(str_read); //从参数表示的地址往后找,找到第一个'\0',即串锋隐尾。计算'\0'至首地址的“距离”,即隔了几个字符,从而得出长度。
printf("密文是:");
for(int i= 0; i< str_read_len; i++)
{
int C= 1; int a= str_read[i], b= a% mod;
for(int j= 0; j< pubKey; j++)//实现加密
{
C=(C*b)% mod;
}
str_encrypt[i]= C;
printf("%d", str_encrypt[i]);
}
printf("\n");
}
//解密函数
void jiemi()
{
int i=0; for(i= 0; i< str_read_len; i++)
{
int C= 1; int a= str_encrypt[i], b=a%mod;
for(int j= 0; j< priKey; j++)
{
C=(C* b)% mod;
}
str_decrypt[i]= C;
}
str_decrypt[i]='\0'; printf("解密文是:%s\n", str_decrypt);
}
int main()
{
srand(time(NULL));
while(1)
{
prime1= randPrime(); prime2= randPrime(); printf("随机产生两个素数:prime1=%d, prime2=%d", prime1, prime2);
mod= prime1* prime2; printf("模数:mod= prime1* prime2=%d\n", mod); if(mod> Element_Max) break;//模数要大于每个加密单元的值
}
eular=(prime1- 1)*(prime2- 1); printf("欧拉数:eular=(prime1-1)*(prime2-1)=%d\n", eular);
pubKey= randExponent(); printf("公钥指数:pubKey=%d\n", pubKey);
priKey= inverse(); printf("私钥指数:priKey=%d\n私钥为(%d,%d)\n", priKey, priKey, mod);
jiami(); jiemi();
return 0;
}
END,本文到此结束,如果可以帮助到大家,还望关注本站哦!
本文来源于互联网,不代表趣虎号立场,转载联系作者并注明出处:https://quhuhao.com/wzfl/8626.html


微信扫一扫