#include?<stdio.h>
#define?MAX_NUM?63001
#define?MAX_PRIME?251
//!?返回代碼
#define?OK?100
#define?ERROR_NOEACHPRIME?101
#define?ERROR_NOPUBLICKEY?102
#define?ERROR_GENERROR?103
unsigned?int?MakePrivatedKeyd(?unsigned?int?uiP,?unsigned?int?uiQ?);
unsigned?int?GetPrivateKeyd(?unsigned?int?iWhich?);
unsigned?int?MakePairkey(?unsigned?int?uiP,?unsigned?int?uiQ,?unsigned?int?uiD?);
unsigned?int?GetPairKey(?unsigned?int?&d,?unsigned?int?&e?);
void?rsa_encrypt(?int?n,?int?e,?char?*mw,?int?iLength,?int?*&cw?);
void?rsa_decrypt(?int?n,?int?d,?int?*&cw,?int?cLength,?char?*mw?);
void?outputkey();
//rsa.c
#include?"rsa.h"
//! 保存私鑰d集合
struct?pKeyset
{
unsigned?int?set[?MAX_NUM?];
unsigned?int?size;
}pset;
//!?保存公、私鑰對
struct?pPairkey
{
unsigned?int?d;
unsigned?int?e;
unsigned?int?n;
}pairkey;
//?名稱:isPrime
//?功能:判斷兩個數是否互質
//?參數:m:?數a;?n:?數b
//?返回:m、n互質返回true;?否則返回false
bool?isPrime(?unsigned?int?m,?unsigned?int?n?)
{
unsigned?int?i=0;
bool?Flag?=?true;
if(?m<2?||?n<2?)
return?false;
unsigned?int?tem?=?(?m?>?n?)n?:?m;
for(?i=2;?i<=tem?&&?Flag;?i++?)
{
bool?mFlag?=?true;
bool?nFlag?=?true;
if(?m?%?i?==?0?)
mFlag?=?false;
if(?n?%?i?==?0?)
nFlag?=?false;
if(?!mFlag?&&?!nFlag?)
Flag?=?false;
}
if(?Flag?)
return?true;
else
return?false;
}
//?名稱:MakePrivatedKeyd
//?功能:由素數Q、Q生成私鑰d
//?參數:uiP:?素數P;?uiQ:?素數Q
//?返回:私鑰d
unsigned?int?MakePrivatedKeyd(?unsigned?int?uiP,?unsigned?int?uiQ?)
{
unsigned?int?i=0;
//!?得到所有與z互質的數(?私鑰d的集合?)
unsigned?int?z?=?(?uiP?-1?)?*?(?uiQ?-1?);
pset.size?=?0;
for(?i=0;?i<z;?i++?)
{
if(?isPrime(?i,?z?)?)
{
pset.set[?pset.size++?]?=?i;
}
}
return?pset.size;
}
//?名稱:MakePairKey
//?功能:生成RSA公、私鑰對
//?參數:uiP:?素數P;?uiQ:?素數Q;?uiD:?私鑰d
//?返回:錯誤代碼
unsigned?int?MakePairkey(?unsigned?int?uiP,?unsigned?int?uiQ,?unsigned?int?uiD?)
{
bool?bFlag?=?true;
unsigned?int?i?=?0,?e;
unsigned?int?z?=?(?uiP-1?)?*?(?uiQ-1?);
unsigned?int?d?=?pset.set[uiD];
//d=uiD;
if(?!isPrime(?z,?d?)?)
return?ERROR_NOEACHPRIME;
for(?i=2;?i<z;?i++?)
{
if(?(i*d)%z?==?1?)
{
e?=?i;
bFlag?=?false;
}
}
if(?bFlag?)
return?ERROR_NOPUBLICKEY;
if(?(d*e)%z?!=?1?)
ERROR_GENERROR;
pairkey.d?=?d;
pairkey.e?=?e;
pairkey.n?=?uiP?*?uiQ;
return?OK;
}
//?名稱:GetPairKey
//?功能:對外提供接口,獲得公、私鑰對
//?參數:uiP:?素數P;?uiQ:?素數Q;?uiD:?私鑰d
//?返回:
unsigned?int?GetPairKey(?unsigned?int?&d,?unsigned?int?&e?)
{
d?=?pairkey.d;
e?=?pairkey.e;
return?pairkey.n;
}
//?名稱:GetPrivateKeyd
//?功能:對外提供接口,由用戶選擇ID得以私鑰d
//?參數:iWhich:?用戶選擇私鑰d的ID
//?返回:私鑰d值
unsigned?int?GetPrivateKeyd(?unsigned?int?iWhich?)
{
if(?pset.size?>=?iWhich?)
return?pset.set[?iWhich?];
else
return?0;
}
//?名稱:rsa_encrypt
//?功能:RSA加密運算
//?參數:n:?公鑰n;?e:?公鑰e;?mw:?加密明文;?iLength:?明文長度;?cw:?密文輸出
//?返回:無
void?rsa_encrypt(?int?n,?int?e,?char?*mw,?int?mLength,?int?*&cw?)
{
int?i=0,?j=0;
__int64?temInt?=?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:?明文輸出
//?返回:無
void?rsa_decrypt(?int?n,?int?d,?int?*&cw,?int?cLength,?char?*mw?)
{
int?i=0,?j=-1;
__int64?temInt?=?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;
}
}
void?outputkey()
{
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"
#define?DECRYPT_FILE?"RSA加密密文.txt"
#define?ENCRYPT_FILE?"RSA解密明文.txt"
//!?約束文件最大2M
#define?MAX_FILE?1024*1024*2
//?名稱:usage
//?功能:幫助信息
//?參數:應用程序名稱
//?返回:提示信息
void?Usage(?const?char?*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;
bool?IsNumber(?const?char?*strNumber?)
{
unsigned?int?i;
if(?!strNumber?)
return?false;
for?(?i?=?0?;?i?<?strlen(strNumber)?;?i++?)
{
if?(?strNumber[i]?<?'0'?||?strNumber[i]?>?'9'?)
return?false;
}
return?true;
}
//?名稱:IsPrimeNumber
//?功能:判斷素數
//?參數:num:?輸入整數
//?返回:素數返回true,否則返回false;
bool?IsPrimeNumber(?unsigned?int?num?)
{
unsigned?int?i;
if(?num?<=?1?)
return?false;
unsigned?int?sqr?=?(unsigned?int)sqrt((double)num);
for(?i?=?2;?i?<=?sqr;?i++?)
{
if(?num?%?i?==?0?)
return?false;
}
return?true;
}
//?名稱:FileIn
//?功能:讀取磁盤文件到內存
//?參數:strFile:文件名稱;inBuff:指向文件內容緩沖區
//?返回:實際讀取內容大小(字節)
int?FileIn(?const?char?*strFile,?unsigned?char?*&inBuff?)
{
int?iFileLen=0,?iBuffLen=0;
//!?打開密文文件
CFile?file(?strFile,?CFile::modeRead?);
iFileLen?=?(?int?)file.GetLength();
if(?iFileLen>MAX_FILE?)
{
printf(?"文件長度不能大於?%dM,!\n",?MAX_FILE/(1024*1024)?);
goto?out;
}
iBuffLen?=?iFileLen;
inBuff?=?new?unsigned?char[iBuffLen];
if(?!inBuff?)
goto?out;
ZeroMemory(?inBuff,?iBuffLen?);
file.Read(?inBuff,?iFileLen?);
file.Close();
out:
return?iBuffLen;
}
//?名稱:FileOut
//?功能:加/解密結果輸出到當前目錄磁盤文件中
//?參數:strOut指向輸出字符緩沖區,輸出大小len,strFile為輸出文件
//?返回:無
void?FileOut(?const?void?*strOut,?int?len,?const?char?*strFile?)
{
//!?輸出到文件
CFile?outfile(?strFile?,?CFile::modeCreate?|?CFile::modeWrite?);
outfile.Write(?strOut?,?len?);
outfile.Close();
}
//?名稱:CheckParse
//?功能:校驗應用程序入口參數
//?參數:argc等於main主函數argc參數,argv指向main主函數argv參數
//?返回:若參數合法返回true,否則返回false
//?備註:簡單的入口參數校驗
bool?CheckParse(?int?argc,?char**?argv?)
{
bool?bRes?=?false;
if(?argc?!=?4?&&?argc?!=?5?)
goto?out;
if(?argc?==?4?&&?argv[1][1]?==?'k'?)
{
//!?生成公、私鑰對
if(?!IsNumber(?argv[2]?)?||?
!IsNumber(?argv[3]?)?||
atoi(?argv[2]?)?>?MAX_PRIME?||
atoi(?argv[3]?)?>?MAX_PRIME?)
goto?out;
}
else?if(?(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?)
goto?out;
}
else
Usage(*argv);
bRes?=?true;
out:
return?bRes;
}
//?名稱:kOption1
//?功能:程序k選項操作:由素數P、Q生成私鑰d集合
//?參數:uiP:?程序入口參數P;?uiQ:?程序入口參數Q
//?返回:執行正確返回生成私鑰數目,否則返回0
unsigned?int?kOption1(?unsigned?int?uiP,?unsigned?int?uiQ?)
{
unsigned?int?uiRes?=?0;
if(?!IsPrimeNumber(?uiP?)?)
{
printf(?"P輸入錯誤,P必須為(0,?%d]素數",?MAX_PRIME?);
return?uiRes;
}
if(?!IsPrimeNumber(?uiQ?)?)
{
printf(?"Q輸入錯誤,Q必須為(0,?%d]素數",?MAX_PRIME?);
return?uiRes;
}
if(?uiP?==?uiQ?)
{
printf(?"素數P與素數Q相同,很容易根據公鑰n開平方得出素數P和Q,這種加密不安全,請更換素數!\n"?);
return?uiRes;
}
printf(?"正在生成私鑰d集合......\n"?);
uiRes?=?MakePrivatedKeyd(?uiP,?uiQ?);
return?uiRes;
}
//!?程序主函數
int?main(?int?argc,?char?**argv?)
{
unsigned?int?p?,?q?,?d?,?n?,?e;//two?prime?p?&?q,?public?key(n,?e)?,?private?key(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();
}
else?if(argc?==?5)
{
char?FileName[20];
strcpy(FileName,?argv[2]);
int?len;
if(argv[1][1]?==?'e'?)
{
unsigned?char?*inBuffer=(unsigned?char?*)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?);
}
else?if(argv[1][1]?==?'d')
{
char?*Buffer=(char?*)malloc(MAX_FILE);?//輸入緩沖區
int?*cw=(int?*)malloc(MAX_FILE);
len?=?FileIn(FileName,?(unsigned?char?*&)cw);
d?=?atoi(argv[3]);
n?=?atoi(argv[4]);
rsa_decrypt(?n,?d,?cw,?len,?Buffer?);
FileOut(?Buffer,?len/4,?ENCRYPT_FILE?);
}
}
return?0;
}