【語言-c++】RSA加密演算法 (C++)
阿新 • • 發佈:2019-02-13
RSAEx.h
/*************************************************/ /*********Author:Cherish *************************/ /*********Date:2015-07-29*************************/ /*******利用大數計算系統實現RSA加密***************/ /*************************************************/ #ifndef _RSAEX_H_ #define _RSAEX_H_ #pragma once #define RSA_P "E34436F5F48A227B" //1>2^64 大素數1>2^63 #define RSA_P1 "E34436F5F48A227A" //1>2^64 大素數1>2^63 #define RSA_Q "A92FA24467C4E3E3" //大素數2 #define RSA_Q1 "A92FA24467C4E3E2" //大素數2 #define RSA_N "963251DC5A9C90D9F203A03C363BA411" //初始化模數n #define RSA_D "56157D29A89D77BF2F669A8F0B123CC9" // #define RSA_E "10001" //初始化公鑰 #define RSA_E1 "10000" //初始化公鑰 #define RSA_KeysizeBits 128 #define RSA_HEX 16 #define RSA_DECIMAL 10 #define RSA_BINARY 2 #define MAX_CHAR_LENGTH 512 #define TST_PT "622H0W1BFEBFBFF0" //測試CPU序列號 明文 非16進位制字串 #define TST_CT "E64D969126CFBAB020221B88C8CFC0D" //繫結IP 密文 16進位制 namespace RSAEx { //CString 轉Char* char* Topchar(const CString &strSource); //定值 加密 char* Encryption(const char* Plaintext); //定值 解密 char* Decryption(const char* Ciphertext); /* 函式功能:加密,得到密文 Plaintext:明文 pChar:素數1參考值,得到的素數大於該值 qChar:素數2參考值,得到的素數大於該值 eChar:公鑰參考值,得到的公鑰大於該值得素數 nType:當前大數計算系統使用的進位制 RSA_HEX = 16進位制;RSA_DECIMAL = 10進位制 return:密文 example: char* p1= RSAEx::EncryptionEx("chenlu","BDCA157F56789A","CDAF9807654312","185642"); char* p2= RSAEx::DecryptionEx(p1,"BDCA157F56789A","CDAF9807654312","185642"); */ char* EncryptionEx(const char* Plaintext ,char* pChar =RSA_P1, char*qChar = RSA_Q1,char* eChar = RSA_E1 , int nType = RSA_HEX); /* 函式功能:加密,得到密文 Plaintext:密文 pChar:素數1參考值,得到的素數大於該值 qChar:素數2參考值,得到的素數大於該值 eChar:公鑰參考值,得到的公鑰大於該值得素數 nType:當前大數計算系統使用的進位制 RSA_HEX = 16進位制;RSA_DECIMAL = 10進位制 return:明文 */ char* DecryptionEx(const char* Ciphetext ,char* pChar =RSA_P1, char*qChar = RSA_Q1,char* eChar = RSA_E1 , int nType = RSA_HEX); /* 函式功能:獲取素數 Plaintext:密文 number:檢測值,得到的素數大於該值 nType:當前大數計算系統使用的進位制 RSA_HEX = 16進位制;RSA_DECIMAL = 10進位制 return: true:素數;false非素數 */ bool IsPrime(const char* number,int nType = RSA_HEX); /* 函式功能:加密,得到密文 Plaintext:密文 pChar:素數參考值,得到的素數大於該值 nType:當前大數計算系統使用的進位制 RSA_HEX = 16進位制;RSA_DECIMAL = 10進位制 return:素數 */ char* CreatePrime(const char* pChar,int nType = RSA_HEX); }; #endif //_RSAEX_H_
RSAEx.cpp
MS32_323K_246B.LIB = MS32.LIB //不同版本包含的函式介面不一樣
#include "StdAfx.h" #include "RSAEx.h" extern "C" { #include "miracl.h" #include "mirdef.h" } //#pragma comment( lib, "ms32_435K_728B.lib" ) //包含計算2的n次冪功能 expb2() //expb2(500, p);//計算2的500次方,2^1024~=1.8*10^308 #pragma comment( lib, "MS32_323K_246B.LIB" ) // 包含兩個大數比較的功能 compare namespace RSAEx { char * Topchar(const CString &strSource) { char* pStrTemp = new char[strSource.GetLength()] ; #ifdef _UNICODE DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,strSource,-1,NULL,0,NULL,FALSE); WideCharToMultiByte (CP_OEMCP,NULL,strSource,-1,pStrTemp,dwNum,NULL,FALSE); pStrTemp[dwNum]=0; #elif//MBCS 工程強轉 pStrTemp = (LPSTR)(LPCTSTR)strSource; #endif return pStrTemp; } bool IsHex(const char* pChar,int nCount) { //檢查SN是否為16進位制 for (int i=0;i<nCount;i++) { if(isxdigit(pChar[i])==false) { OutputDebugString(L"字串誰不是16進位制的\n"); return false; } } return true; } char* Decryption(const char* Ciphertext ) { // char SN[256] = {0}; char* SN= new char[MAX_CHAR_LENGTH]; for (int i = 0 ; i < MAX_CHAR_LENGTH ;i ++) SN[i] ='\0'; //拷貝字元床 strcpy(SN, Ciphertext); //獲取字串長度 int len = (int)strlen(SN); //判斷字串長度是否大於0 if (len<=0) { delete[] SN; return NULL; } //判斷是否是16進位制 if(!IsHex(SN,len)) { delete SN; return NULL; } //初始化Miracl系統 100位 0進位制 miracl *mip=mirsys(100,0); //設定計算模式 mip->IOBASE=RSA_HEX; //16進位制模式 //定義並初始化變數 big m=mirvar(0); //m 放明文:註冊碼SN big c=mirvar(0); //c 放密文:使用者名稱Name big n=mirvar(0); //n 模數 big e=mirvar(0); //e 公鑰 // char ret[256]={0}; char* ret= new char[MAX_CHAR_LENGTH]; for (int i = 0 ; i < MAX_CHAR_LENGTH ;i ++) ret[i] ='\0'; //賦值 cinstr(m,SN); //初始化明文m cinstr(n,RSA_N); cinstr(e,RSA_E); //當m<n時 //if(compare(m,n)==-1) //{ powmod(m,e,n,c);//加密:計算c=m^e mod n big_to_bytes(MAX_CHAR_LENGTH,c,ret,FALSE);//將c轉換成陣列寫入temp //釋放記憶體 mirkill(m); mirkill(c); mirkill(n); mirkill(e); mirexit(); delete[] SN; return ret; //} //else //{ // delete[] SN; // return NULL; //} } char* Encryption (const char* Plaintext ) { char* SN= new char[MAX_CHAR_LENGTH]; for (int i = 0 ; i < MAX_CHAR_LENGTH ;i ++) SN[i] ='\0'; //拷貝字元床 strcpy(SN, Plaintext); //獲取字串長度 int len = (int)strlen(SN); //判斷字串長度是否大於0 if (len<=0) { delete[] SN; return NULL; } //判斷是否是16進位制 /*if(!IsHex(SN,len)) { delete SN; return NULL; }*/ //初始化Miracl系統 100位 0進位制 miracl *mip=mirsys(100,0); //設定計算模式 mip->IOBASE=RSA_HEX; //16進位制模式 //定義並初始化變數 big m=mirvar(0); //m 放明文:註冊碼SN big c=mirvar(0); //c 放密文:使用者名稱Name big n=mirvar(0); //n 模數 big d=mirvar(0); //e 公鑰 // char ret[256]={0}; char* ret= new char[MAX_CHAR_LENGTH]; for (int i = 0 ; i < MAX_CHAR_LENGTH ;i ++) ret[i] ='\0'; //賦值 bytes_to_big(len,SN,c); //cinstr(m,SN); //初始化明文m cinstr(n,RSA_N); cinstr(d,RSA_D); //當m<n時 //if(compare(m,n)==-1) //{ powmod(c,d,n,m);//加密:計算c=m^e mod n cotstr(m,ret); //big_to_bytes(256,c,ret,FALSE);//將c轉換成陣列寫入temp //釋放記憶體 mirkill(m); mirkill(c); mirkill(n); mirkill(d); mirexit(); delete[] SN; return ret; //} //else //{ delete[] SN; return NULL; //} //return NULL; } //加密 char* EncryptionEx(const char* Plaintext , char* pChar , char* qChar, char* eChar , int nType ) { char* SN= new char[MAX_CHAR_LENGTH]; for (int i = 0 ; i < MAX_CHAR_LENGTH ;i ++) SN[i] ='\0'; //拷貝字元床 strcpy(SN, Plaintext); //獲取字串長度 int len = (int)strlen(SN); //判斷字串長度是否大於0 if (len<=0) { delete[] SN; return NULL; } miracl *mip = mirsys(400,10); //初始化一個400位10進位制的大數系統 /************************ 第一節 獲取初始值 *********************************/ //下面進行RSA演算法加密和解密運算 char* ret= new char[MAX_CHAR_LENGTH]; for (int i = 0 ; i < MAX_CHAR_LENGTH ;i ++) ret[i] ='\0'; big m=mirvar(0); //m 明文 big c=mirvar(0); //c 密文 big p=mirvar(0); //大素數p big q=mirvar(0); //大素數q big n=mirvar(0); //n 模數 big pn=mirvar(0); //尤拉函式值pn = (p - 1)(q - 1) big d=mirvar(0); //d 私鑰 big e=mirvar(0); //e 公鑰 mip->IOBASE=nType; /************************ step1 獲取p值 = [ 素數p>p ] *********************************/ cinstr(p,pChar); nxprime(p,p);//找一個比p大的素數;測試p是否為素數isprime(p) cotnum(q, stdout); /************************ step2 獲取q值 = [ 素數q>q ] *********************************/ cinstr(q,qChar); nxprime(q,q); /************************ step3 獲取n值 = [ n=p*q ] *********************************/ multiply(p, q, n); //cotstr(n,ret); /************************ step4 獲取pn值 = [ n=(p-1)*(q-1) ] *********************************/ decr(p, 1, p); //p = p - 1 decr(q, 1, q); //q = q - 1 multiply(p, q, pn); //pn = (p - 1)(q - 1) /************************ step5 獲取e值 = [素數e>e] *********************************/ cinstr(e,eChar); nxprime(e,e); /************************ step6 獲取d值 = [ d= e^-1 mod pn] *********************************/ xgcd(e, pn, d, d, d); //計算d = e^-1 mod n /************************ step7 加密大數字[c=m^e mod n] *********************************/ bytes_to_big(len, SN, m); //字串的明文,轉換成大數 powmod(m,e,n,c); //計算c=m^e mod n // std::cout<<"c="; cotnum(c, stdout); cotstr(c,ret); //將大數轉換成當前進位制的字串 mirkill(m); //釋放大數變數 mirkill(c); mirkill(p); mirkill(q); mirkill(d); mirkill(e); mirkill(n); mirkill(pn); mirexit(); return ret; } char* DecryptionEx(const char* Ciphetext , char* pChar , char* qChar, char* eChar , int nType) { char* SN= new char[MAX_CHAR_LENGTH]; for (int i = 0 ; i < MAX_CHAR_LENGTH ;i ++) SN[i] ='\0'; //拷貝字元床 strcpy(SN, Ciphetext); //獲取字串長度 int len = (int)strlen(SN); //判斷字串長度是否大於0 if (len<=0) { delete[] SN; return NULL; } char* ret= new char[MAX_CHAR_LENGTH]; for (int i = 0 ; i < MAX_CHAR_LENGTH ;i ++) ret[i] ='\0'; miracl *mip = mirsys(400,10); //初始化一個400位10進位制的大數系統 /************************ 第一節 獲取初始值 *********************************/ big m=mirvar(0); //m 明文 big c=mirvar(0); //c 密文 big p=mirvar(0); //大素數p big q=mirvar(0); //大素數q big n=mirvar(0); //n 模數 big pn=mirvar(0); //尤拉函式值pn = (p - 1)(q - 1) big d=mirvar(0); //d 私鑰 big e=mirvar(0); //e 公鑰 mip->IOBASE=nType; /************************ step1 獲取p值 = [ 素數p>p ] *********************************/ cinstr(p,pChar); nxprime(p,p);//找一個比p大的素數;測試p是否為素數isprime(p) cotnum(q, stdout); /************************ step2 獲取q值 = [ 素數q>q ] *********************************/ cinstr(q,qChar); nxprime(q,q); /************************ step3 獲取n值 = [ n=p*q ] *********************************/ multiply(p, q, n); //cotstr(n,ret); /************************ step4 獲取pn值 = [ n=(p-1)*(q-1) ] *********************************/ decr(p, 1, p); //p = p - 1 decr(q, 1, q); //q = q - 1 multiply(p, q, pn); //pn = (p - 1)(q - 1) /************************ step5 獲取e值 = [素數e>e] *********************************/ cinstr(e,eChar); nxprime(e,e); /************************ step6 獲取d值 = [ d= e^-1 mod pn] *********************************/ xgcd(e, pn, d, d, d); //計算d = e^-1 mod n /************************ step7 解密 [m=c^d mod n] *********************************/ cinstr(c,SN); //當前進位制的字串轉換成相應進位制的大數 powmod(c,d,n,m); //計算m=c^d mod n // std::cout<<"m="; cotnum(m, stdout); big_to_bytes(MAX_CHAR_LENGTH,m,ret,FALSE);//將大數轉換成字串 mirkill(m); //釋放大數變數 mirkill(c); mirkill(p); mirkill(q); mirkill(d); mirkill(e); mirkill(n); mirkill(pn); mirexit(); return ret; } bool IsPrime( const char* iData ,int nType) { bool bret = false; char* SN= new char[MAX_CHAR_LENGTH]; for (int i = 0 ; i < MAX_CHAR_LENGTH ;i ++) SN[i] ='\0'; //拷貝字元床 strcpy(SN, iData); //獲取字串長度 int len = (int)strlen(SN); //判斷字串長度是否大於0 if (len<=0) { delete[] SN; return NULL; } miracl *mip = mirsys(400,10); //初始化一個400位10進位制的大數系統 mip->IOBASE=nType; big t=mirvar(0); //m 明文 cinstr(t,SN); if(isprime(t) == TRUE) bret =true; mirkill(t); mirexit(); delete[] SN; return bret; } char* CreatePrime( const char* iData,int nType /*= RSA_HEX*/ ) { bool bret = false; char* SN= new char[MAX_CHAR_LENGTH]; for (int i = 0 ; i < MAX_CHAR_LENGTH ;i ++) SN[i] ='\0'; //拷貝字元床 strcpy(SN, iData); //獲取字串長度 int len = (int)strlen(SN); //判斷字串長度是否大於0 if (len<=0) { delete[] SN; return NULL; } miracl *mip = mirsys(400,10); //初始化一個400位10進位制的大數系統 mip->IOBASE=nType; big t=mirvar(0); //m 明文 cinstr(t,SN); nxprime(t,t); cotstr(t,SN); mirkill(t); mirexit(); return SN; } };