⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 advance.cpp

📁 这学期刚学密码学
💻 CPP
字号:
// Advance.cpp : implementation file
//

#include "stdafx.h"
#include "RSA Tool.h"
#include "Advance.h"
#include "BigNumber.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
const char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAdvance property page

IMPLEMENT_DYNCREATE(CAdvance, CPropertyPage)

CAdvance::CAdvance() : CPropertyPage(CAdvance::IDD)
{
	//{{AFX_DATA_INIT(CAdvance)
	m_keylen = 0;
	KeyEmpty = 1;
	//}}AFX_DATA_INIT
}

CAdvance::~CAdvance()
{
}

void CAdvance::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAdvance)
	DDX_Control(pDX, IDC_CLEAR, m_CLEAR);
	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_KEYLEN, m_KEYLEN);
	DDX_CBIndex(pDX, IDC_KEYLEN, m_keylen);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CAdvance, CPropertyPage)
	//{{AFX_MSG_MAP(CAdvance)
	ON_BN_CLICKED(IDC_GENERATEKEYS, OnGeneratekeys)
	ON_BN_CLICKED(IDC_DECRYPT, OnDecrypt)
	ON_BN_CLICKED(IDC_ENCRYPT, OnEncrypt)
	ON_BN_CLICKED(IDC_SAVEKEYS, OnSavekeys)
	ON_BN_CLICKED(IDC_SAVECLT, OnSaveclt)
	ON_BN_CLICKED(IDC_SAVECIT, OnSavecit)
	ON_BN_CLICKED(IDC_OPENKEYS, OnOpenkeys)
	ON_BN_CLICKED(IDC_OPENCLT, OnOpenclt)
	ON_BN_CLICKED(IDC_OPENCIT, OnOpencit)
	ON_BN_CLICKED(IDC_CLEAR, OnClear)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAdvance message handlers

void CAdvance::OnGeneratekeys() 
{
	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];//N, D有可能超过300字节但是不会超过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);
	AfxMessageBox("密钥生成成功");
}

void CAdvance::OnDecrypt() 
{
	unsigned i = 0;
	char szPlain[MAX_PATH], szBuf[MAX_PATH];
	CString strTemp, strResult, strReplace;
	CBigNumber bnCIT, bnCLT, bnD, bnN;
	unsigned nIndex = 0;
	SYSTEMTIME before, after;
	char elapsed[10];
	
	if ( m_cit.GetLength() == 0 ){
		AfxMessageBox("请导入密文");
		return ;
	}
	
	bnD.Init(0);
	bnN.Init(0);
	if ( KeyEmpty == 1 ){
		AfxMessageBox("密钥为空,请导入密钥");
		return ;
	}
	
	GetLocalTime(&before);
	bnCIT.Init(0);
	bnCLT.Init(0);
	m_clt = "";

	while(i < iCount){
	
		strTemp = m_cit.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);
	
		strReplace = szBuf;
		m_clt += strReplace;	// 连接明文
		i++;
		
	}

	GetLocalTime(&after);	// 计算花费时间
	bnCIT.GetElapsedTime(elapsed, before, after);
	m_Showtime.SetWindowText(elapsed);
	D.Init(0);
	N.Init(0);
	AfxMessageBox("解密完毕");	
}

void CAdvance::OnEncrypt() 
{
	CString strCipher;
	CBigNumber bnCipher, bnE, bnResult;		
	CString strBlock, strResult, strReplace;
	unsigned BlockSize = 12;	// 分组长度12字节,96比特
	unsigned long PlainSize;				// 明文转化成数字后的长度
	unsigned long Blocks = 0;				// 分组数
	BOOL finished = TRUE;
	unsigned long i = 0,  j = 0, nIndex = 0, nBytes;
	SYSTEMTIME before, after;
	char szLength[6];
	char elapsed[10];
	char temp1[MAX_PATH], temp2[MAX_PATH], szCipher[350];;
	
	GetLocalTime(&before);
	if ( m_clt.GetLength() == 0 ){
		AfxMessageBox("请导入明文");
		return ;
	}


	PlainSize = m_clt.GetLength();
	bnE.Init(0);
	
	if (E.Cmp(bnE) == 0){		// 公钥为0
		AfxMessageBox("请先生成或导入密钥");
		return ;
	}
	
	if (PlainSize % 12 != 0)	// 计算分组数
		Blocks = PlainSize / (unsigned long)BlockSize + 1;
	else
		Blocks = PlainSize / (unsigned long)BlockSize;
	
	bnCipher.Init(0);
	iCount = 0;  
	while(finished){
		if (PlainSize - i < BlockSize)
			BlockSize = PlainSize - i;
		strBlock = m_clt.Mid(i, BlockSize);
		memset(temp1, 0, MAX_PATH);
		memset(temp2, 0, MAX_PATH);
		CLT.StringToChars(temp1, strBlock);
		
		CLT.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);	// 加密后的数字转化成字符串

		strReplace = szCipher;
		iLength[iCount++] = strlen(szCipher);	// 记录一次加密后密文的长度 
		itoa(strlen(szCipher), szLength, 10);	
		
		nBytes = strlen(szLength);						// 把密文长度装换成字符串
		for (j = 0; j < 5; j++){					// 密文的前四个字节保存一个分组被加密后的长度,
			if ( j >= nBytes )						// 如果有剩,则用空格填充
				m_cit += ' ';
			else
				m_cit += szLength[j];	
		}
		
		m_cit += strReplace;						// 一个分组的前面的数字是该分组的字节数,便于解密	
		i += BlockSize;			
		
		if ((unsigned long)i >= PlainSize)
			finished = FALSE;
	}
		
	GetLocalTime(&after);
	CLT.GetElapsedTime(elapsed, before, after);
	m_Showtime.SetWindowText(elapsed);
	AfxMessageBox("加密成功");
}

void CAdvance::OnSavekeys() 
{
	char	strN[350], strE[MAX_PATH], strD[350];
	CBigNumber bnD, bnE, bnN;
	CString  buf, FilePath;
	char *szbuf;
	const char szFilter[] = "文本文件(*.txt)|*.txt";
	int dlen, elen, nlen, i, pos;
	
	bnD.Init(0);
	bnE.Init(0);
	bnN.Init(0);
	
	if (D.Cmp(bnD) == 0 || N.Cmp(bnN) == 0){
		AfxMessageBox("密钥为空,请先生成密钥");
		return ;
	}
		
	D.BigNumberToString(strD);	// 把大数形式密钥转换成字符串形式
	E.BigNumberToString(strE);
	N.BigNumberToString(strN);
	dlen = strlen(strD);	// 获取密钥长度
	elen = strlen(strE);
	nlen = strlen(strN);
	szbuf = new char[dlen + nlen + elen + 6];
	memset(szbuf, 0, dlen + nlen + elen + 6);
	
	
	for (i = 0; i < dlen; i++)	// 首先保存D
		*(szbuf + i) = strD[i];
	*(szbuf + i++) = '\r';	// 加入回车换行符
	*(szbuf + i++) = '\n';

	pos = i;
	for (i = pos; i < pos + elen; i++)	// 然后爆出E
		*(szbuf + i) = strE[i - pos];
	*(szbuf + i++) = '\r';	// 加入回车换行符
	*(szbuf + i++) = '\n';
	
	pos = i;
	for (i = pos; i  < pos + nlen; i++)	// 最后保存N
		*(szbuf + i) = strN[i - pos];
	*(szbuf + i) = '\0';
	
	CFileDialog dlg(FALSE, NULL, NULL, NULL, szFilter);
	if (dlg.DoModal() == IDOK){
		FilePath = dlg.GetPathName();	// 获取目录名
		if (FilePath.Right(4) != ".txt")	// 只给出文件名,则加上扩展名,否则不用加
			FilePath += ".txt";
		CFile mFile(FilePath, CFile::modeCreate | CFile::modeWrite);	// 读写方式打开
		mFile.Write(szbuf, strlen(szbuf));	// 写文件
		AfxMessageBox("密钥保存成功");
		delete []szbuf;
	}	
}

void CAdvance::OnSaveclt() 
{
	char *buf;
	int ilen;
	const char szFilter[] = "文本文件(*.txt)|*.txt";
	CString FilePath, str_CLT;
	CBigNumber bn;
	
	ilen = m_clt.GetLength();
	if (ilen == 0){
		AfxMessageBox("明文为空");
		return ;
	}
	
	CFileDialog dlg(FALSE, NULL, NULL, NULL,szFilter);
	
	if (dlg.DoModal() == IDOK){
		FilePath = dlg.GetPathName();
		if (FilePath.Right(4) != ".txt")	// 只给出文件名,则加上扩展名,否则不用加
			FilePath += ".txt";
		
		CFile mFile(FilePath, CFile::modeCreate | CFile::modeWrite);
		ilen = m_clt.GetLength();
		buf = new char[ilen + 1];
		memset(buf, 0, ilen+1);
		bn.StringToChars(buf, m_clt);
		buf[ilen] = '\0';
		mFile.WriteHuge(buf, ilen);
		AfxMessageBox("明文保存成功");
		delete []buf;
	}	
	D.Init(0);
	E.Init(0);
	N.Init(0);
}

void CAdvance::OnSavecit() 
{
	char *buf;
	int iLen;
	const char szFilter[] = "文本文件(*.txt)|*.txt";
	CString FilePath, str_CIT;
	CFileDialog dlg(FALSE, NULL, NULL, NULL,szFilter);
	
	iLen = m_cit.GetLength();
	if (iLen == 0){
		AfxMessageBox("密文为空");
		return ;
	}
	
	if (dlg.DoModal() == IDOK){
		FilePath = dlg.GetPathName();
		if (FilePath.Right(4) != ".txt")	// 只给出文件名,则加上扩展名,否则不用加
			FilePath += ".txt";
		
		CFile mFile(FilePath, CFile::modeCreate | CFile::modeWrite);
		
		buf = new char[iLen + 1];
		memset(buf, 0, iLen+1);
		CIT.StringToChars(buf, m_cit);
		buf[iLen] = '\0';
		mFile.WriteHuge(buf, iLen);
		AfxMessageBox("密文保存成功");
		delete []buf;
	}	
	
}

void CAdvance::OnOpenkeys() // 密钥读取后,D, N即被赋值,以便进行解密
{
	CString strN, strE, strD;
	const char szFilter[] = "文本文件(*.txt)|*.txt";
	CString FilePath;
	char *buf;
	int i, pos;
	int FileSize;
	CFileDialog dlg(TRUE, NULL, NULL, NULL,szFilter);
	
	if (dlg.DoModal() == IDOK){
		FilePath = dlg.GetPathName();	// 获取目录名
		CFile mFile(FilePath, CFile::modeRead);	// 以读方式打开文件
		FileSize = mFile.GetLength() + 1;
		if (FileSize == 1){
			AfxMessageBox("密钥为空");
			return ;
		}
		buf = new char[FileSize];
		memset(buf, 0, FileSize);
		mFile.Read(buf, FileSize);	// 读取文件
		
		// 首先读入D,遇到回车换行符D结束
		for (i = 0; i < FileSize; i++){
			strD += *(buf + i);
			if ( *(buf + i) == '\r' )
				break;
		}
		
		// 然后读入E,遇到回车换行符E结束
		pos = i + 2;	
		for (i = pos; i < FileSize; i++){
			strE += *(buf + i);
			if ( *(buf + i) == '\r' )									
				break;		
		}
	
		// 最后读入N,遇到回车换行符节结束
		pos = i + 2;	
		for (i = pos; i < FileSize; i++){
			strN += *(buf + i);
			if ( *(buf + i) == '\r' )
				break;
		}
		
		/////////////////////////////////////////
		//////去掉最后的'\0',否则前功尽弃,//////
		strD.Delete(strD.GetLength()-1, 1);	
		strE.Delete(strE.GetLength()-1, 1);
		strN.Delete(strN.GetLength()-1, 1);
		/////////////////////////////////////////
		/////////////////////////////////////////

		if (strD.GetLength() > 350) {
			AfxMessageBox("打开的不是密钥文件");// 如果打开错误文件,可能引起越界出错!
			return;
		}
		D.Init(0);
		E.Init(0);
		N.Init(0);
		D.StringToBigNumber(strD);	// 把读取的密钥转换成大数形式
		E.StringToBigNumber(strE);
		N.StringToBigNumber(strN);
		m_D.SetWindowText(strD);	// 在对话框中显示密钥
		m_E.SetWindowText(strE);
		m_N.SetWindowText(strN);
		AfxMessageBox("密钥读取成功");
		KeyEmpty = 0;
		delete []buf;
	}
}

void CAdvance::OnOpenclt() // 读取明文后,全局变量m_clt(CString)保存明文的值
{
	const char szFilter[] = "文本文件(*.txt)|*.txt";
	CString FilePath;
	char *buf;
	unsigned long FileSize;
	CFileDialog dlg(TRUE, NULL, NULL, NULL,szFilter);
	
	if ( dlg.DoModal() == IDOK ){
		FilePath = dlg.GetPathName();
		CFile mFile(FilePath, CFile::modeRead);
		FileSize = mFile.GetLength() + 1;
		if ( FileSize == 1 ){
			AfxMessageBox("明文为空");
			return ;
		}
		buf = new char[FileSize];
		memset(buf, 0, FileSize);
		mFile.ReadHuge(buf, FileSize);
		m_clt = buf;
		AfxMessageBox("明文读取成功");
		delete []buf;
	}

}

void CAdvance::OnOpencit() // 读取密文后,全局变量m_cit(CStirng)保存密文的值,以便进行加密
{
	const char szFilter[] = "文本文件(*.txt)|*.txt";
	CString FilePath, strTemp;
	char *buf, bloSize[4]; //因为1024bit最多128字节,128在文件上占3个字节,剩下一个结束符
	unsigned long FileSize, nIndex = 0;
	int citlen;
	unsigned i, j, k = 0;

	CFileDialog dlg(TRUE, NULL, NULL, NULL,szFilter);
	
	if ( dlg.DoModal() == IDOK ){
		FilePath = dlg.GetPathName();	// 得到文件的路径
		CFile mFile(FilePath, CFile::modeRead);	// 以读方式打开文件
		FileSize = mFile.GetLength() + 1;	// 得到文件大小
	
		if (FileSize == 1){
			AfxMessageBox("密文为空");
			return ;
		}

		buf = new char[FileSize];
		memset(buf , 0, FileSize);
		mFile.ReadHuge(buf, FileSize);	// 读取密文
		if (buf[3] != ' ') {	// 因为文件格式为每组密文开头共四个字节,前三字节组合的数字为改组的字节数,第四字节为空格
			// 因为这样对1024bit的密钥最多是个三位数,所以4字节够用了。如果不检测,如果密文被破坏,解密会失败,甚至引起程
			// 序崩溃
			AfxMessageBox("密文文件格式错误");
			delete []buf;
			return ;
		}	

		iCount = 0;
		m_cit = "";
		while(1){
			memset(bloSize, 0, 4);
			strTemp = "";
			
			for (i = 0; i < 3; i++)
				bloSize[i] = buf[nIndex + i];
			bloSize[3] = '\0';
			nIndex += 5;
			citlen = atoi(bloSize);
			for (j = nIndex; j < nIndex + citlen; j++)
				strTemp += buf[j];
			m_cit += strTemp;
			iLength[iCount++] = citlen;
			nIndex += citlen;
					
			if (buf[nIndex] == '\0')
				break;
		}
		delete []buf;
		AfxMessageBox("密文读取成功");
	}	
}

void CAdvance::OnClear() 
{
	P.Init(0);
	Q.Init(0);
	D.Init(0);
	E.Init(0);
	N.Init(0);
	EUL.Init(0);
	m_clt = "";
	m_cit = "";
	m_P.SetWindowText("");
	m_Q.SetWindowText("");
	m_E.SetWindowText("");
	m_D.SetWindowText("");
	m_N.SetWindowText("");
	m_Showtime.SetWindowText("");
	KeyEmpty = 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -