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