一、说明
RSA算法既能用于数据加密,也能用于数字签名。其理论依据是:寻找两个大素数容易,而将它们的乘积分解开则异常困难。在RSA算法中,包含两对密钥:公有密钥对和私有密钥对。公有密钥对是公开的。
二、密钥产生过程
(1)选择两个大素数p和q,p和q均大于10100,n = p * q,z = (p - 1) * (q - 1);
(2)随机选择加密密钥e,使e与z互质;
(3)求解d,使 e * d = 1(mod z),且n和d也要互质。(n,e)是公有密钥对,(n,d)是私有密钥对。
Code:
// CRSAKey.h
class CRSAKey
{
public:
CRSAKey();
~CRSAKey();
void ProduceKey();
private:
bool IsPrime(unsigned int unData); // 判断素数
bool IsRelativelyPrime(unsigned int unData1, unsigned int unData2); // 判断互为素数
private:
unsigned int m_unRSAN;
unsigned int m_unRSAE;
unsigned int m_unRSAD;
}
// CRSAKey.cpp
#include <ctime>
#include <cmtah>
CRSAKey::CRSAKey() : m_RSAN(0), m_RSAE(0), m_RSAD(0)
{}
CRSAKey::~CRSAKey(){}
void CRSAKey::ProduceKey()
{
unsigned int unRSAP;
unsigned int unRSAQ;
srand(UINT(time(NULL)));
do
{
unRSAP = (rand() % 1000) + 1;
unRSAQ = (rand() % 1000) + 1;
}while(!(IsPrime(unRSAP) && (IsPrime(unRSAQ))));
m_unRSAN = unRSAP * unRSAQ;
unsigned int unRSAZ = (unRSAP - 1) * (unRSAQ - 1);
do
{
m_unRSAE = (rand() % 99) + 1;
} while (!IsRelativelyPrime(m_unRSAE, unRSAZ));
while(!(1 == ((m_unRSAE * m_unRSAD) % unRSAZ) && IsRelativelyPrime(m_unRSAD, m_unRSAN)))
{
m_unRSAD++;
}
return TRUE;
}
bool CRSAKey::IsPrime(unsingned int unData)
{
unsigned int limit = (unsigned int )sqrt( (double)unData );
for(UINT i = 2; i <= limit; i++)
{
if(0 == unData % i)
{
return FALSE;
}
}
return TRUE;
}
bool CRSAKey::IsRelativelyPrime(unsigned int unData1, unsigned int unData2)
{
if (unData1 < unData2)
{
unData1 = unData1 + unData2;
unData2 = unData1 - unData2;
unData1 = unData1 - unData2;
}
while (0 != unData2)
{
UINT unTemp = unData2;
unData2 = unData1 % unData2;
unData1 = unTemp;
}
return (1 == unData1);
}
三、RSA算法加密解密过程
(1)加密过程:假设"ABCD"需要解密,并取其ASCII值作为其对应的值unAscii。则某字符加密后的对应的数值
C = unAscii^m_unRSAE(mod m_unRSAN);
将C值发送给对方解密。
(2)解密过程:接收到C值后,进行解密后对应的数值
M = C^m_unRSAD(mod m_unRSAN);
在对应表中找到M值对应的字符。
上述加密解密过程中可以看出,由于密钥对(m_unRSAN, m_unRSAE)是公开的,因而解密方必须知道私有密钥对(m_unRSAN, m_unRSAD)。
Code:
// CRSA.h
#include <string>
class CRSA
{
public:
CRSA(){};
CRSA(){};
string EnCryption(const string &strSrc);
string DnCryption(const string &strSrc);
private:
static const unsigned int m_scunPKEY[2];
static const unsigned int m_scunSKEY[2];
}
// CRSA.cpp
const unsigned int m_m_scunPKEY[2] = {329, 85};
const unsigned int m_m_scunSKEY[2] = {329, 85};
string CRSA::EnCryption(const string &strSrc)
{
size_t stSrcLen = strSrc.length();
if (0 == stSrcLen)
{
return "";
}
string strRet;
for (size_t i = 0; i < stSrcLen; i++)
{
unsigned int wAscii = (unsigned int )strSrc[i];
unsigned int wModel = 1;
for (UINT j = 0; j < m_scunPKEY[1]; j++)
{
wModel *= wAscii;
if (wModel > m_scunPKEY[0])
{
wModel %= m_scunPKEY[0];
if (0 == wModel && i < (stSrcLen - 1))
{
wModel = 1;
}
}
}
wModel %= m_scunPKEY[0];
char *pModel = (char *)&wModel;
string strModel(pModel, sizeof(UINT));
strRet += strModel;
}
return strRet;
}
string CRSA::DeCryption(const string &strSrc)
{
size_t stSrcLen = strSrc.length();
if (0 == stSrcLen)
{
return "";
}
string strRet;
const char *pSrc = strSrc.c_str();
for (size_t i = 0; i < stSrcLen; i += 4)
{
unsigned int wAscii;
memcpy(&wAscii, pSrc + i, 4);
unsigned int wModel = 1;
for (unsigned int j = 0; j < m_scunPrivateKey[1]; j++)
{
wModel *= wAscii;
if (wModel > m_scunPrivateKey[0])
{
wModel %= m_scunPrivateKey[0];
if (0 == wModel && i < (stSrcLen - 1))
{
wModel = 1;
}
}
}
wModel %= m_scunPublicKey[0];
char cChar = (char)wModel;
strRet += cChar;
}
return strRet;
}