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

📄 secretchatdlg.cpp

📁 一个用RSA算法实现加密通信的聊天程序。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		AfxGetResourceHandle(),
		hRsrc);
	::sndPlaySound(
		(LPCTSTR)::LockResource(hglb),
		SND_MEMORY | SND_SYNC | SND_NODEFAULT);
	::FreeResource(hglb);
	/**********************************/
}

BOOL CSecretChatDlg::Disconnection()	//断开连接
{	
	if(!m_online)	//联机时的处理
		return TRUE;
	/*正在发送或接收消息时不能断开连接,否则会出现严重的错误提示
	if(m_send != 0 || m_receive != -1)
	{
		MessageBox(
			"发送或接收消息时,请别断开连接",
			"密聊",
			MB_ICONEXCLAMATION);
		return FALSE;
	}*/


	m_statusMessages.SetWindowText("已经断开连接");	//已经断开服务器连接
	
	//断开连接成功后改变按钮的状态
	CString str = "连接";
	m_connect.SetIcon(IDI_CONNECT);
	m_connect.SetTooltipText(&str);	
	m_connect.SetWindowText(str);

	/*这里有些逻辑错误,双方会造成循环发送HEAD_DISCONNECTION消息
	MessagePackage	msg;
	msg.head = HEAD_DISCONNECTION;
	SendData(msg, 12);
	*/
	m_online = FALSE;	//提示断线
	TrayIcon();	//设置状态区图标
	SetWindowText("密聊 (未连接)");	//提示已连接还是未连接

	//关闭套接字
	CloseSocket();//断开了那还怎么发通知断线消息给对方呀?
	PlayWaveSound(IDR_OFFLINE);	//断开时的声音提示

	return TRUE;
}

BOOL CSecretChatDlg::Connect()			//建立连接
{	
	if(m_online)	//没联机时的处理
		return TRUE;

	if(m_connectDlg.DoModal() != IDOK)
	{
		return FALSE;
	}

	m_IP = m_connectDlg.m_IP;
	m_port = m_connectDlg.m_port;

	if(!prevent_connect())
		return FALSE;	//防止自己连接自己

	m_statusMessages.SetWindowText("连接中...");

	/*连接不能在线程了完成否则对方无法创建得到服务器套接字对象,
	所以就发不了消息给客户机了*/
	if( (NULL != (m_pSocket = new CClientSocket)) //确定了指向那个套接字
		&& m_pSocket->Create() )		//创建套接字对象
	{
		if(m_pSocket->Connect(m_IP, m_port) )
		{	
			//成功连接的IP地址记入注册表中
			AfxGetApp()->WriteProfileString("Connect", "IPHistory", m_IP);
			m_clientOrService = FALSE;	//客户端
			connect_succeed_update();
		}
		else
		{
			CloseSocket();//关闭套接字
			m_statusMessages.SetWindowText("连接失败!");
			PlayWaveSound(IDR_OFFLINE);	//连接失败时的声音提示
			return FALSE;
		}
	}
	else
	{
		return FALSE;
	}
	/*
	unsigned long nThreadID;
	::CreateThread(
		NULL,
		0,
		connect_thread,
		this,
		0,
		&nThreadID);*/

	return TRUE;
}

int CSecretChatDlg::SendData(MessagePackage &msg, int n)	//发送数据
{
	//断开连接就不能再发送消息了
	if(!m_online)
		return 0;

	if(m_clientOrService)	//服务器端
	{
		m_socketListen.m_pServiceSocket->Send(&msg, n);
		//错误提示
		CuoWuTiShi();
	}
	else					//客户机端
	{
		m_pSocket->Send(&msg, n);
		//错误提示
		CuoWuTiShi();
	}
	return 0;

}

void CSecretChatDlg::WinHelp(DWORD dwData, UINT nCmd) //按下F1打开帮助文件
{
	::ShellExecute( 
		m_hWnd, 
		"open",
		"http://www.wjmshome.com/SecretChat.htm",
		"", 
		"", 
		SW_SHOWNORMAL);
	
	//CDialog::WinHelp(dwData, nCmd);
}

void CSecretChatDlg::OnSecretkey() //通讯双方的密钥设置和密钥管理
{
	m_setupDlg.m_index = 0;
	if(m_setupDlg.DoModal() == IDOK)
	{

	}
}

void CSecretChatDlg::OnSetup()		//常规设置
{
	m_setupDlg.m_index = 3;
	if(m_setupDlg.DoModal() == IDOK)
	{

	}
	
}

BOOL CSecretChatDlg::InstallPrivateKey(CString fileName/*安装的文件名*/)
{
	if(fileName == "")
	{	//当没说明安装的文件时,就安装默认的
		fileName =
			m_appName 
			+ "\\user\\" 
			+ AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey");
	}

	CFile file;
	SecretKey secretKey;
	if(!file.Open(
		fileName,
		CFile::modeReadWrite | CFile::typeBinary))
		return FALSE;
	if(file.GetLength() != sizeof(SecretKey))
		return FALSE;
	file.SeekToBegin();
	file.Read(&secretKey, sizeof(SecretKey));
	file.Close();

	if(secretKey.ID != SECRETKEY_ID)
		return FALSE;
	if(secretKey.privateOrPublic != SECRETKEY_PRIVATE)
		return FALSE;

	m_userNameStatic.SetWindowText(AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey"));
	m_userNameStatic.SetLink(TRUE,FALSE);
	m_userNameStatic.SetTextColor(RGB(0,128,192));
	m_userNameStatic.SetLinkCursor(AfxGetApp()->LoadCursor( IDC_HAND));

	m_private_key_send.SK_to_vlong(secretKey.sk/*自己的私钥*/);
	m_private_key_receive.SK_to_vlong(secretKey.sk/*自己的私钥*/);

	return TRUE;
}

BOOL CSecretChatDlg::InstallPublicKey(CString fileName/*安装的文件名*/)
{
	if(fileName == "")
	{	//当没说明安装的文件时,就安装默认的
		fileName =
			m_appName 
			+ "\\friend\\" 
			+ AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey");
	}

	CFile file;
	SecretKey secretKey;
	if(!file.Open(
		fileName,
		CFile::modeReadWrite | CFile::typeBinary))
		return FALSE;
	if(file.GetLength() != sizeof(SecretKey))
		return FALSE;
	file.SeekToBegin();
	file.Read(&secretKey, sizeof(SecretKey));
	file.Close();

	if(secretKey.ID != SECRETKEY_ID)
		return FALSE;
	if(secretKey.privateOrPublic != SECRETKEY_PUBLIC)
		return FALSE;

	m_friendNameStatic.SetWindowText(AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey"));
	m_friendNameStatic.SetLink(TRUE,FALSE);
	m_friendNameStatic.SetTextColor(RGB(255,128,128));
	m_friendNameStatic.SetLinkCursor(AfxGetApp()->LoadCursor( IDC_HAND));

	m_public_key_send.PK_to_vlong(secretKey.pk/*对方的公钥*/);
	m_public_key_receive.PK_to_vlong(secretKey.pk/*对方的公钥*/);

	return TRUE;
}

BOOL CSecretChatDlg::MyUpdateData() //根据注册表数据进行设置
{
	//显示出私钥和公钥名
	m_userNameStatic.SetWindowText(
		AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey"));
	m_friendNameStatic.SetWindowText(
		AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey"));
	m_userNameStatic.SetLink(TRUE,FALSE);
	m_userNameStatic.SetTextColor(RGB(0,128,192));
	m_userNameStatic.SetLinkCursor(AfxGetApp()->LoadCursor( IDC_HAND));
	m_friendNameStatic.SetLink(TRUE,FALSE);
	m_friendNameStatic.SetTextColor(RGB(255,128,128));
	m_friendNameStatic.SetLinkCursor(AfxGetApp()->LoadCursor( IDC_HAND));

	//顶层窗口
	if(AfxGetApp()->GetProfileInt("General", "Top", 0))
	{
		::SetWindowPos(
			GetSafeHwnd(),
			HWND_TOPMOST,
			0,0,0,0,
			SWP_NOMOVE | SWP_NOSIZE);
	}
	else
	{
		::SetWindowPos(
			GetSafeHwnd(),
			HWND_NOTOPMOST,
			0,0,0,0,
			SWP_NOMOVE | SWP_NOSIZE);
	}

	//显示位置
	TrayIcon();

	//LAN启动周期性连接
	if(AfxGetApp()->GetProfileInt("General", "LANStartup", 0))
	{
		SetTimer(1002, 60000, NULL);	//以60秒为周期连接LAN
	}
	else
	{
		KillTimer(1002);
	}

	//安装私钥和公钥
	InstallPrivateKey();
	InstallPublicKey();


	return TRUE;

}

BOOL CSecretChatDlg::PreTranslateMessage(MSG* pMsg) 
{
	//快捷键
	if( pMsg->message == WM_KEYDOWN)
	{
		BOOL bCtrl = ::GetKeyState( VK_CONTROL) & 0x8000;
		BOOL bShift = ::GetKeyState( VK_SHIFT) & 0x8000;
		BOOL bAlt = ::GetKeyState( VK_MENU) & 0x8000;

		switch( pMsg->wParam)
		{
		case VK_ESCAPE:	//不能Esc就退出程序
			if(AfxGetApp()->GetProfileInt("General", "Tray", 1))
			{
				ShowWindow( SW_MINIMIZE);
				ShowWindow(SW_HIDE);		//隐藏动画
			}
			else
			{	
				ShowWindow( SW_MINIMIZE);
			}
			return TRUE;	//必须要立即返回
			break;
		case VK_RETURN:
			if( bCtrl)
			{
				SendMessage( WM_COMMAND, IDC_SEND);
				return TRUE;
			}
			break;
		case 'J':
			if( bCtrl)
			{
				HKEY hkey;
				char sz[MAX_PATH];	//缓冲区必须要和设置时的相同才能读到数据
				DWORD dwtype, sl = MAX_PATH;
				::RegOpenKeyEx(
					HKEY_CURRENT_USER,
					"Software\\文件密使\\Application",
					NULL,
					KEY_ALL_ACCESS,
					&hkey);
				::RegQueryValueEx(
					hkey,
					"DirectoryName",
					NULL,
					&dwtype,
					(LPBYTE)sz,
					&sl);
				::RegCloseKey(hkey);
				CString strJiaMi = sz;

				::ShellExecute(
					NULL, 
					"open",
					strJiaMi + "\\jiami.exe", 
					"", 
					"",
					SW_SHOW);
				return TRUE;
			}
			break;
		}
	}

	//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
	m_toolTip.RelayEvent(pMsg);	//
	//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%	
	return CDialog::PreTranslateMessage(pMsg);
}

void CSecretChatDlg::OnUsername() //查看用户的私钥信息
{
	CSecretKeyEdit secretKeyEditDlg;
	secretKeyEditDlg.m_select = SECRETKEY_PRIVATE;
	if(secretKeyEditDlg.validateSecretKey(
		m_appName 
		+ "\\user\\" 
		+ AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey"))
		!= SECRETKEY_PRIVATE)
	{
		MessageBox(
			"不是用户私钥文件",
			"密聊",
			MB_ICONINFORMATION);
		return;
	}
	secretKeyEditDlg.DoModal();

}

void CSecretChatDlg::OnFriendname() //查看好友的公钥信息
{
	CSecretKeyEdit secretKeyEditDlg;
	secretKeyEditDlg.m_select = SECRETKEY_PUBLIC;
	if(secretKeyEditDlg.validateSecretKey(
		m_appName 
		+ "\\friend\\" 
		+ AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey"))
		!= SECRETKEY_PUBLIC)
	{
		MessageBox(
			"不是好友公钥文件",
			"密聊",
			MB_ICONINFORMATION);
		return;
	}
	secretKeyEditDlg.DoModal();
	
}

BOOL CSecretChatDlg::AskPublicKey()	//请求获得连线好友的公钥文件
{
	if(m_online)
	{
		MessagePackage	msg;
		msg.head = HEAD_CLAIM_PUBLIC_KEY;
		SendData(msg, sizeof(msg));
		return TRUE;
	}
	else
	{	
		MessageBox(
			"需要联机才能请求获得对方的公钥文件",
			"密聊",
			MB_ICONINFORMATION);
		return FALSE;
	}

}

BOOL CSecretChatDlg::ClaimPublicKey(MessagePackage &msg)	//请求对方的公钥
{
	//生成公钥信息
	SecretKey secretKey;
	CFile file;
	if(!file.Open(
		m_appName + "\\user\\" + AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey"),
		CFile::modeReadWrite | CFile::typeBinary))
		return FALSE;
	if(file.GetLength() != sizeof(SecretKey))
		return FALSE;
	file.SeekToBegin();
	file.Read(&secretKey, sizeof(SecretKey));
	file.Close();

	//清除私钥信息
	char chTemp[2048 / 8];
	for(int i = 0;i < (2048 / 8);i++)
	{
		chTemp[i] = 0;
	}
	::MoveMemory(
		(char *)&secretKey.sk,	//目标
		chTemp,					//源内容
		2048 / 8);
	secretKey.privateOrPublic = SECRETKEY_PUBLIC;//公钥标记

	msg.head = HEAD_REVERT_PUBLIC_KEY;	//回复给对方
	::MoveMemory(
		msg.data,							//目标
		(char *)&secretKey,					//源内容
		sizeof(SecretKey));	//公钥文件信息包涵公钥文件名

	SendData(msg, sizeof(msg));

	return TRUE;
}

BOOL CSecretChatDlg::RevertPublicKey(MessagePackage &msg)	//接收对方的公钥
{
	SecretKey secretKey;
	CSecretKeyEdit secretKeyEditDlg;
	CString fileName;
	CFile file;
	CFileFind find;
	::MoveMemory(
		(char *)&secretKey,	//目标
		msg.data,			//源内容
		sizeof(SecretKey));	//公钥文件信息包涵公钥文件名

	fileName = //密钥的文件全路径
		m_appName 
		+ "\\friend\\" 
		+ secretKeyEditDlg.CharToCString(secretKey.userName, 32) 
		+ ".pk";

	if(find.FindFile(fileName)) //文件存在
	{	
		MessageBox(
			"对方的公钥文件 " 
			+ secretKeyEditDlg.CharToCString(secretKey.userName, 32)
			+ ".pk 已经存在",
			"密聊",
			MB_ICONEXCLAMATION);
		return FALSE;
	}
	//生成公钥文件
	file.Open(
		fileName,//密钥的文件全路径
		CFile::modeCreate | CFile::modeReadWrite | CFile::typeBinary);
	file.Write(
		&secretKey,
		sizeof(SecretKey));	//写入信息
	file.Close();

⌨️ 快捷键说明

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