//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);
unsignedintd=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) ",pairkey.e,pairkey.n);
printf("PrivateKey(d,n):(%d,%d) ",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(" usage:rsa-k素数P素数Q ");
printf(" usage:rsa-e明文文件公钥e公钥n ");
printf(" usage:rsa-d密文文件私钥d私钥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,! ",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,这种加密不安全,请更换素数! ");
returnuiRes;
}
printf("正在生成私钥d集合...... ");
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;
}
‘贰’ 如何用C++实现RSA算法
RSA算法介绍及java实现,其实java和c++差不多,参考一下吧
<一>基础
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->(); $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->(); $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 娃哈哈哈~~~
加密串:
解密串:RSA 娃哈哈哈~~~
C:\Temp>perl rsa-test.pl 安全焦点(xfocus)
N=2773 D=847 E=63
原始串:安全焦点(xfocus)
加密串:
解密串:安全焦点(xfocus)
<四>提高
前面已经提到,rsa的安全来源于n足够大,我们测试中使用的n是非常小的,根本不能保障安全性,
我们可以通过RSAKit、RSATool之类的工具获得足够大的N 及D E。
通过工具,我们获得1024位的N及D E来测试一下:
n=EC3A85F5005D
4C2013433B383B
A50E114705D7E2
BC511951
d=0x10001
e=DD28C523C2995
47B77324E66AFF2
789BD782A592D2B
1965
设原始信息
M=
完成这么大数字的计算依赖于大数运算库,用perl来运算非常简单:
A) 用d对M进行加密如下:
c=M**d%n :
C:\Temp>perl -Mbigint -e " $x=Math::BigInt->bmodpow(0x11111111111122222222222233
333333333, 0x10001,
D55EDBC4F0
6E37108DD6
);print $x->as_hex"
b73d2576bd
47715caa6b
d59ea89b91
f1834580c3f6d90898
即用d对M加密后信息为:
c=b73d2576bd
47715caa6b
d59ea89b91
f1834580c3f6d90898
B) 用e对c进行解密如下:
m=c**e%n :
C:\Temp>perl -Mbigint -e " $x=Math::BigInt->bmodpow(0x17b287be418c69ecd7c39227ab
5aa1d99ef3
0cb4764414
, 0xE760A
3C29954C5D
7324E66AFF
2789BD782A
592D2B1965, CD15F90
4F017F9CCF
DD60438941
);print $x->as_hex"
(我的P4 1.6G的机器上计算了约5秒钟)
得到用e解密后的m= == 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.hasMoreTokens()){
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 molar
* 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 molar domain over which to perform this operation
* @return <tt>base</tt>^<sup><tt>pow</tt></sup> within the molar
* 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加密算法怎样用C语言实现 急急急!!!
/*数据只能是大写字母组成的字符串。
加密的时候,输入Y,然后输入要加密的文本(大写字母)
解密的时候,输入N,然后输入一个整数n表示密文的个数,然后n个整数表示加密时候得到的密文。
*/
/*RSA algorithm */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MM 7081
#define KK 1789
#define PHIM 6912
#define PP 85
typedef char strtype[10000];
int len;
long nume[10000];
int change[126];
char antichange[37];
void initialize()
{ int i;
char c;
for (i = 11, c = 'A'; c <= 'Z'; c ++, i ++)
{ change[c] = i;
antichange[i] = c;
}
}
void changetonum(strtype str)
{ int l = strlen(str), i;
len = 0;
memset(nume, 0, sizeof(nume));
for (i = 0; i < l; i ++)
{ nume[len] = nume[len] * 100 + change[str[i]];
if (i % 2 == 1) len ++;
}
if (i % 2 != 0) len ++;
}
long binamod(long numb, long k)
{ if (k == 0) return 1;
long curr = binamod (numb, k / 2);
if (k % 2 == 0)
return curr * curr % MM;
else return (curr * curr) % MM * numb % MM;
}
long encode(long numb)
{ return binamod(numb, KK);
}
long decode(long numb)
{ return binamod(numb, PP);
}
main()
{ strtype str;
int i, a1, a2;
long curr;
initialize();
puts("Input 'Y' if encoding, otherwise input 'N':");
gets(str);
if (str[0] == 'Y')
{ gets(str);
changetonum(str);
printf("encoded: ");
for (i = 0; i < len; i ++)
{ if (i) putchar('-');
printf(" %ld ", encode(nume[i]));
}
putchar('\n');
}
else
{ scanf("%d", &len);
for (i = 0; i < len; i ++)
{ scanf("%ld", &curr);
curr = decode(curr);
a1 = curr / 100;
a2 = curr % 100;
printf("decoded: ");
if (a1 != 0) putchar(antichange[a1]);
if (a2 != 0) putchar(antichange[a2]);
}
putchar('\n');
}
putchar('\n');
system("PAUSE");
return 0;
}
/*
测试:
输入:
Y
FERMAT
输出:
encoded: 5192 - 2604 - 4222
输入
N
3 5192 2604 4222
输出
decoded: FERMAT
*/
‘肆’ 如何用C语言实现RSA算法
上学期交的作业,已通过老师在运行时间上的测试
#include <stdio.h>
#include <stdlib.h>
unsigned long prime1,prime2,ee;
unsigned long *kzojld(unsigned long p,unsigned long q) //扩展欧几里得算法求模逆
{
unsigned long i=0,a=1,b=0,c=0,d=1,temp,mid,ni[2];
mid=p;
while(mid!=1)
{
while(p>q)
{p=p-q; mid=p;i++;}
a=c*(-1)*i+a;b=d*(-1)*i+b;
temp=a;a=c;c=temp;
temp=b;b=d;d=temp;
temp=p;p=q;q=temp;
i=0;
}
ni[0]=c;ni[1]=d;
return(ni);
}
unsigned long momi(unsigned long a,unsigned long b,unsigned long p) //模幂算法
{
unsigned long c;
c=1;
if(a>p) a=a%p;
if(b>p) b=b%(p-1);
while(b!=0)
{
while(b%2==0)
{
b=b/2;
a=(a*a)%p;
}
b=b-1;
c=(a*c)%p;
}
return(c);
}
void RSAjiami() //RSA加密函数
{
unsigned long c1,c2;
unsigned long m,n,c;
n=prime1*prime2;
system("cls");
printf("Please input the message:\n");
scanf("%lu",&m);getchar();
c=momi(m,ee,n);
printf("The cipher is:%lu",c);
return;
}
void RSAjiemi() //RSA解密函数
{
unsigned long m1,m2,e,d,*ni;
unsigned long c,n,m,o;
o=(prime1-1)*(prime2-1);
n=prime1*prime2;
system("cls");
printf("Please input the cipher:\n");
scanf("%lu",&c);getchar();
ni=kzojld(ee,o);
d=ni[0];
m=momi(c,d,n);
printf("The original message is:%lu",m);
return;
}
void main()
{ unsigned long m;
char cho;
printf("Please input the two prime you want to use:\n");
printf("P=");scanf("%lu",&prime1);getchar();
printf("Q=");scanf("%lu",&prime2);getchar();
printf("E=");scanf("%lu",&ee);getchar();
if(prime1<prime2)
{m=prime1;prime1=prime2;prime2=m;}
while(1)
{
system("cls");
printf("\t*******RSA密码系统*******\n");
printf("Please select what do you want to do:\n");
printf("1.Encrpt.\n");
printf("2.Decrpt.\n");
printf("3.Exit.\n");
printf("Your choice:");
scanf("%c",&cho);getchar();
switch(cho)
{ case '1':RSAjiami();break;
case '2':RSAjiemi();break;
case '3':exit(0);
default:printf("Error input.\n");break;
}
getchar();
}
}
‘伍’ C++实现RSA加密解密算法
#include <iostream>
using namespace std;
template <class HugeInt>
HugeInt Power( const HugeInt & x, const HugeInt & n, // 求x^n mod p
const HugeInt & p )
{
if( n == 0 )
return 1;
HugeInt tmp = Power( ( x * x ) % p, n / 2, p );
if( n % 2 != 0 )
tmp = ( tmp * x ) % p;
return tmp;
}
template <class HugeInt>
void fullGcd( const HugeInt & a, const HugeInt & b, //
HugeInt & x, HugeInt & y )
{
HugeInt x1, y1;
if( b == 0 )
{
x = 1;
y = 0;
}
else
{
fullGcd( b, a % b, x1, y1 );
x = y1;
y = x1 - ( a / b ) * y1;
}
}
template <class HugeInt>
HugeInt inverse( const HugeInt & p, const HugeInt & q, // 求d
const HugeInt & e )
{
int fyn = ( 1 - p ) * ( 1 - q );
HugeInt x, y;
fullGcd( fyn, e, x, y );
return x > 0 ? x : x + e;
}
int main( )
{
cout << "Please input the plaintext: " << endl;
int m;
cin >> m;
cout << "Please input p,q and e: " << endl;
int p, q, e;
cin >> p >> q >> e;
int n = p * q;
int d = inverse( p, q, e );
int C = Power( m, e, n );
cout << "The ciphertext is: " << C << endl;
cout << "\n\nPlease input the ciphertext: " << endl;
cin >> C;
cout << "\n\nPlease input p, q and d: " << endl;
cin >> p >> q >> d;
n = p * q;
m = Power( C, d, n );
cout <<"The plaintext is: " << m << endl << endl;
system( "pause" );
return 0;
}
这就是RSA加密解密算法