古詩詞大全網 - 個性簽名 - 求正確的RSA加密解密算法C語言的,多謝。

求正確的RSA加密解密算法C語言的,多謝。

//rsa.h

#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;

}