📄 common.cpp
字号:
// Common.cpp : implementation file
//
#include "stdafx.h"
#include "RSA Tool.h"
#include "Common.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCommon property page
IMPLEMENT_DYNCREATE(CCommon, CPropertyPage)
CCommon::CCommon() : CPropertyPage(CCommon::IDD)
{
//{{AFX_DATA_INIT(CCommon)
m_keylen = 0;
m_cit = _T("");
m_clt = _T("");
IsEncrypt = 1;
SameCipher = 0;
//}}AFX_DATA_INIT
}
CCommon::~CCommon()
{
}
void CCommon::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCommon)
DDX_Control(pDX, IDC_CLTR, m_CLTR);
DDX_Control(pDX, IDC_TIME, m_Showtime);
DDX_Control(pDX, IDC_Q, m_Q);
DDX_Control(pDX, IDC_P, m_P);
DDX_Control(pDX, IDC_N, m_N);
DDX_Control(pDX, IDC_E, m_E);
DDX_Control(pDX, IDC_D, m_D);
DDX_Control(pDX, IDC_CLT, m_CLT);
DDX_Control(pDX, IDC_KEYLEN, m_KEYLEN);
DDX_Control(pDX, IDC_CIT, m_CIT);
DDX_CBIndex(pDX, IDC_KEYLEN, m_keylen);
DDX_Text(pDX, IDC_CIT, m_cit);
DDX_Text(pDX, IDC_CLT, m_clt);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCommon, CPropertyPage)
//{{AFX_MSG_MAP(CCommon)
ON_BN_CLICKED(IDC_GENERATEKYS, OnGeneratekys)
ON_BN_CLICKED(IDC_ENCRYPT, OnEncrypt)
ON_BN_CLICKED(IDC_DECRYPT, OnDecrypt)
ON_BN_CLICKED(IDC_CLEAR, OnClear)
ON_WM_CTLCOLOR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCommon message handlers
void CCommon::OnGeneratekys()
{
CBigNumber bnP, bnQ, bnE, bnN, bnD, bnCMP;
SYSTEMTIME before, after;
char elapsed[10];
char strP[MAX_PATH], strQ[MAX_PATH], strE[MAX_PATH], strN[350], strD[350];
int len=2;
for(int i = 0; i < m_KEYLEN.GetCurSel(); i++)
{
len *= 2;
}
//初始化
GetLocalTime(&before);
P.Init(0);
Q.Init(0);
N.Init(0);
EUL.Init(0);
E.Init(0);
D.Init(0);
bnP.Init(0);
bnQ.Init(0);
bnE.Init(0);
// 生成指定bit的大数
P.GetPrime(len);
Q.GetPrime(len);
bnP.Init(P);
bnQ.Init(Q);
bnP.BigNumberToString(strP); // 把数组形式的大数转化成字符串
bnQ.BigNumberToString(strQ);
N.Init(bnP.Mul(bnQ)); // 计算 N = P * Q
bnN.Init(N);
bnN.BigNumberToString(strN);
bnP.Init(P);
bnQ.Init(Q);
bnP.m_ulValue[0]--; // P - 1
bnQ.m_ulValue[0]--; // Q - 1
EUL.Init(bnP.Mul(bnQ)); // EUL = (P-1) * (Q-1)
do{
bnE.GetPrime(len); // 产生指定位数的公钥,这里以素数作为公钥,可以节省时间,但公钥的范围小了
bnCMP.Init(0);
}while(((N.Mod(bnE)).Cmp(bnCMP)) == 0); // 产生的数与欧拉函数值除1外还有其他公因子
E.Init(bnE);
bnE.BigNumberToString(strE);
D.Init(E.SolEqu(EUL)); // 计算私钥
bnD.Init(D);
bnD.BigNumberToString(strD);
GetLocalTime(&after); // 计算花费时间
memset(elapsed, 0, 10);
bnP.GetElapsedTime(elapsed, before, after);
m_Showtime.SetWindowText(elapsed);
m_P.SetWindowText(strP); // 在对话框中输出大数
m_Q.SetWindowText(strQ);
m_N.SetWindowText(strN);
m_E.SetWindowText(strE);
m_D.SetWindowText(strD);
}
void CCommon::OnEncrypt()
{
char szCipher[350];
CString strCipher, strClt, szBuf, strTemp, strBlock, strResult;
CBigNumber bnPlain, bnCipher, pk, bnResult;
unsigned BlockSize = 12; // 分组长度12字节,96比特
unsigned long PlainSize; // 明文转化成数字后的长度
unsigned long Blocks = 0; // 分组数
BOOL finished = TRUE; // 加密完成与否的标志
unsigned long i = 0, j = 0, k = 0, nIndex = 0;
SYSTEMTIME before, after;
char elapsed[10];
GetLocalTime(&before);
m_cit = "";
bnPlain.Init(0);
m_CLT.GetWindowText(strClt); // 获取用户输入的明文
PlainSize = (unsigned long)strClt.GetLength(); // 计算明文长度
if (E.Cmp(bnPlain) == 0){
AfxMessageBox("请先产生密钥!");
return ;
}
if (PlainSize == 0){
AfxMessageBox("请输入明文!");
return ;
}
if (PlainSize % 12 != 0) // 计算分组数
Blocks = PlainSize / (unsigned long)BlockSize + 1;
else
Blocks = PlainSize / (unsigned long)BlockSize;
iCount = Blocks;
iLength = new unsigned long[iCount]; // 动态分配空间保存每次加密后的密文长度
bnCipher.Init(0);
char temp1[MAX_PATH];
char temp2[MAX_PATH];
while(finished){
if (PlainSize - i < BlockSize) // 最后剩下的长度不足一个分组
BlockSize = PlainSize - i;
strBlock = strClt.Mid(i, BlockSize); // 获取分组
bnPlain.StringToChars(temp1, strBlock);
bnPlain.CharsToNumber(temp2, temp1); // 把数字化的分组转换成字符串
strResult = temp2;
bnResult.Init(0);
bnResult.StringToBigNumber(strResult); // 把字符串转换成大数
bnCipher.Init(bnResult.RsaEn(E, N)); // 加密
memset(szCipher, 0, MAX_PATH);
bnCipher.BigNumberToString(szCipher); // 把大数转换成数字
iLength[j++] = strlen(szCipher); // 得到每个密文分组的长度
strTemp += szCipher; // 把密文连接在一起,可能包含结束符
i += BlockSize;
if ((unsigned long)i >= PlainSize)
finished = FALSE;
}
IsEncrypt = 0;
GetLocalTime(&after); // 计算花费时间
pk.GetElapsedTime(elapsed, before, after);
m_Showtime.SetWindowText(elapsed);
m_CIT.SetWindowText(strTemp);
}
void CCommon::OnDecrypt()
{
if (IsEncrypt != 0 && SameCipher == 0){
AfxMessageBox("请先进行加密!");
return ;
}
if (SameCipher == 1){
AfxMessageBox("已解密过相同的密文!");
return ;
}
unsigned i = 0;
CString strCipher, strPlain, strTemp, strResult, strBuf;
CBigNumber bncit, bnclt;
int nIndex = 0;
SYSTEMTIME before, after;
char elapsed[10];
char szPlain[MAX_PATH];
char szBuf[MAX_PATH];
GetLocalTime(&before);
bncit.Init(0);
bnclt.Init(0);
m_CIT.GetWindowText(strCipher); // 得到密文
while(i < iCount){
strTemp = strCipher.Mid(nIndex, iLength[i]); // 获取与加密后长度对应的密文
nIndex += iLength[i];
// iLength[i]里面是保存的每次读取的字节数
bncit.Init(0);
bncit.StringToBigNumber(strTemp); // 把字符串转换成大数
bnclt.Init(bncit.RsaEn(D, N)); // 解密
memset(szPlain, 0, MAX_PATH);
memset(szBuf, 0, MAX_PATH);
bnclt.BigNumberToString(szPlain); // 把大数转换成数字
bnclt.NumberToChars(szBuf, szPlain); // 把数字转换成明文
if (m_cit.GetLength() > 0){
m_cit.Delete(m_cit.GetLength()-1, 1);
}
m_cit += szBuf; // 连接明文
m_cit += '0'; // 后移一个字节,以防前一个字节被替代,我发现m_cit的最后一个字节会被替换掉,但不知道原因。
i++;
}
m_cit.SetAt(m_cit.GetLength()-1, '\0');
strPlain = m_cit;
IsEncrypt = 1; // 此时不能再解密
delete []iLength;
m_CLTR.SetWindowText(strPlain);
GetLocalTime(&after);
bncit.GetElapsedTime(elapsed, before, after);
m_Showtime.SetWindowText(elapsed);
}
void CCommon::OnClear()
{
m_CLT.SetWindowText(""); // 用空串代替
m_CIT.SetWindowText("");
P.Init(0); // 清零
Q.Init(0);
N.Init(0);
D.Init(0);
E.Init(0);
EUL.Init(0);
m_P.SetWindowText("");
m_Q.SetWindowText("");
m_N.SetWindowText("");
m_E.SetWindowText("");
m_D.SetWindowText("");
m_CLTR.SetWindowText("");
m_CLT.SetWindowText("");
m_CIT.SetWindowText("");
m_Showtime.SetWindowText("");
}
HBRUSH CCommon::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CPropertyPage::OnCtlColor(pDC, pWnd, nCtlColor);
COLORREF bkcolor;
if (pWnd->GetDlgCtrlID() == IDC_CLT) {
bkcolor = RGB(0, 255, 0);
HBRUSH hBrush = CreateSolidBrush(bkcolor);
pDC->SetBkColor(bkcolor);
return hBrush;
}
return hbr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -