📄 secretchatdlg.cpp
字号:
//把注册表好友公钥文件名改成现在的连线好友
AfxGetApp()->WriteProfileString(
"SecretKeySetup",
"FriendPublicKey",
secretKeyEditDlg.CharToCString(secretKey.userName, 32) + ".pk");
//提示成功
MessageBox(
"已经获得公钥 " + AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey"),
"密聊",
MB_ICONINFORMATION);
MyUpdateData(); //更新设置
return TRUE;
}
BOOL CSecretChatDlg::ValidatePrivateKey() //验证私钥的设置情况
{
//连接之情必须要有一个私钥并且要有一个被选中
WIN32_FIND_DATA wfd;
HANDLE hSearch;
//判断是否至少有一个私钥文件
hSearch = ::FindFirstFile(
m_appName + "\\user\\*.sk" ,
&wfd);
if(hSearch == INVALID_HANDLE_VALUE)
{ //没有私钥存在,就要提示生成新的密钥
MessageBox(
"没有任何用户私钥文件,请先创建新的密钥",
"密聊",
MB_ICONINFORMATION);
CSecretKeyEdit secretKeyEditDlg;
secretKeyEditDlg.m_select = SELECT_CREATE;
secretKeyEditDlg.DoModal();
return FALSE; //没有生成密钥将永远不能进行连接
}
hSearch = ::FindFirstFile(
m_appName
+ "\\user\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey"),
&wfd);
if(hSearch == INVALID_HANDLE_VALUE)
{ //没有选择私钥,提示要选择
MessageBox(
"通讯前必须选择用户私钥文件",
"密聊",
MB_ICONINFORMATION);
m_setupDlg.m_index = 1;
m_setupDlg.DoModal(); //选择私钥和公钥
return FALSE; //没有选中将永远不能进行连接
}
//还有判断它是合格的私钥文件
CSecretKeyEdit secretKeyEditDlg;
if(secretKeyEditDlg.validateSecretKey(
m_appName
+ "\\user\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey")) != SECRETKEY_PRIVATE)
{
MessageBox(
AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey") + " 不是合格的私钥文件",
"密聊",
MB_ICONINFORMATION);
m_setupDlg.m_index = 1;
m_setupDlg.DoModal();
return FALSE; //不合格将永远不能进行连接
}
if(!InstallPrivateKey()) //安装私钥文件
{
MessageBox(
"无法安装用户私钥文件",
"密聊",
MB_ICONINFORMATION);
return FALSE;
}
return TRUE;
}
BOOL CSecretChatDlg::ValidatePublicKey() //验证公钥的设置情况
{
WIN32_FIND_DATA wfd;
HANDLE hSearch;
//连接成功后,就要判断有没好友公钥
//判断是否至少有一个公钥文件
hSearch = ::FindFirstFile(
m_appName + "\\friend\\*.pk" ,
&wfd);
if(hSearch == INVALID_HANDLE_VALUE)
{ //没有公钥存在,就要提示请求获取新的公钥
if(MessageBox(
"没有任何好友公钥文件,是否请求获取对方的公钥?",
"密聊",
MB_YESNO | MB_ICONQUESTION) == IDYES)
{ //获取对方的公钥
AskPublicKey();
}
return FALSE;
}
//查看公钥是否被选中
hSearch = ::FindFirstFile(
m_appName
+ "\\friend\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey"),
&wfd);
if(hSearch == INVALID_HANDLE_VALUE)
{ //没有选择公钥,提示要选择和获取新的公钥
if(MessageBox(
"请选择好友公钥文件或请求获取对方的公钥,\r\n是否请求获取对方的公钥?",
"密聊",
MB_YESNO | MB_ICONQUESTION) == IDYES)
{ //获取对方的公钥
AskPublicKey();
}
else
{
m_setupDlg.m_index = 2;
m_setupDlg.DoModal();
}
return FALSE;
}
//还有判断它是合格的公钥文件
CSecretKeyEdit secretKeyEditDlg;
if(secretKeyEditDlg.validateSecretKey(
m_appName
+ "\\friend\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey")) != SECRETKEY_PUBLIC)
{
MessageBox(
AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey") + " 不是合格的公钥文件",
"密聊",
MB_ICONINFORMATION);
m_setupDlg.m_index = 2;
m_setupDlg.DoModal();
return FALSE; //不合格将永远不能进行连接
}
if(!InstallPublicKey()) //安装公钥文件
{
MessageBox(
"无法安装好友公钥文件",
"密聊",
MB_ICONINFORMATION);
return FALSE;
}
return TRUE;
}
LRESULT CSecretChatDlg::RunHide(WPARAM wParam,LPARAM lParam) //运行时隐藏窗口
{
if(wParam == 0)
{
ShowWindow(SW_HIDE); //隐藏窗口
MoveWindow(m_rect);
return 0;
}
if(wParam == 1)//询问打开接收到的文件
{
if(MessageBox(
"是否打开 " + m_receive_file_name + " 文件?",
"密聊",
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDYES)
{
::ShellExecute(
NULL,
"open",
m_receive_file_name,
"",
"",
SW_SHOW);
}
return 0;
}
if(wParam == 2)
{
int arithmometer(0);
while(!(ValidatePrivateKey() && ValidatePublicKey()))
{//必须要把私钥和公钥安装好了,才能开始接收消息
if(arithmometer++ == 5)
break;
};
if(arithmometer != 5)
{ //向对方发送"你好!我们可以进行安全通话了。"
}
}
return 0;
}
void CSecretChatDlg::TrayIcon() //设置状态区图标
{
if(AfxGetApp()->GetProfileInt("General", "Tray", 1))
{
//必须先删除图标才能用这种方法更改任务栏状态区图标
MyTaskBarDeleteIcon(
101,
m_hWnd);
if(m_online)
{
MyTaskBarAddIcon(
m_hWnd,
101,
m_hOnline,
"文件密使 - 密聊(已连接)");//在任务栏状态区添加图标
}
else
{
MyTaskBarAddIcon(
m_hWnd,
101,
m_hOffline,
"文件密使 - 密聊(未连接)");//在任务栏状态区添加图标
}
}
else
{
MyTaskBarDeleteIcon(
101,
m_hWnd); //从任务栏状态区删除图标
}
}
void CSecretChatDlg::TextToMessagePackage(MessagePackage &package, CString strm) //将明文strm转化成消息包
{
MessageDollop *pDollop;
__DWORD128 b1, b2;
int quotient, remainder, i, j;
CSecretKeyEdit secretKeyEditDlg; //只为了转换时间格式
char chm[DATA_LENGTH]; //明文
// package.n/*明文长度*/ = strm.GetLength();
secretKeyEditDlg.CStringToChar(chm, strm, package.n);
quotient = (package.n * 2) / sizeof(MessageDollop);
remainder = (package.n * 2) % sizeof(MessageDollop);
if(remainder != 0)
{
quotient++;
//多余的补零
for(i = package.n;i < (package.n + (int)sizeof(MessageDollop) / 2 - remainder);i++)
{
chm[i] = 0;
}
}
pDollop = new MessageDollop[quotient]; //消息块是消息包的元素
//分配每条消息块和总消息包的ID
b2.Nil();
for(i = 0;i < quotient;i++)
{
b1.RandCount(); //没有生成随机的数吗?
b2 = b2 + b1;
b1.Store(pDollop[i].messageDollop_ID/*每个消息块的ID*/);
}
/* for(int s = 0;s < 32;s++)
{
if(b2 == m_send_message_package_ID[s])
{ //这里表示b1.RandCount()没有生成随机数
//TRACE("这里出错了");
AfxMessageBox("出现了相同的随机数了");
}
}*/
//把它添加到发送消息ID数组中,可以等下查询
m_send_message_package_ID_add(b2/*这里b2变成了消息包的ID了*/);
//获得当前的时间
CTime time = CTime::GetCurrentTime();
m_send_time = time.Format("%Y-%m-%d %H:%M:%S");
//写入数字标识
b1.DigitalID();//这里b1变成了数字标识了
for(i = 0;i < quotient;i++)
{
//把消息块合并成消息包
//必须为0,否则会无法进行加解密
pDollop[i].nil[0] = 0;
//消息包ID
b2.Store(pDollop[i].messagePackage_ID);
//数字标识
b1.Store(pDollop[i].digital_ID);
//发送时间
secretKeyEditDlg.CStringToChar(
pDollop[i].time,
m_send_time,
20);
//获得正文内容
::MoveMemory(
pDollop[i].text,
chm + i * sizeof(MessageDollop) / 2,
sizeof(MessageDollop) / 2);//除2是因为只要得到正文信息
//设置随机数
srand((unsigned)::GetTickCount()); //播撒随机数的种子,rand()才能生成随机数
for(j = 0;j < 16;j++)
{
pDollop[i].randCount[j] = (char)(0x41+rand()%0xAF);
//pDollop[j应该是i的这样会产生无法回复的错误].randCount[j] = (char)rand();
}
//把信息存储到消息包中
::MoveMemory(
package.data + i * sizeof(MessageDollop),//目标
(char *)&pDollop[i], //源内容
sizeof(MessageDollop));
}
//设置消息包的头信息
package.head = HEAD_TEXT;
delete[] pDollop;
}
void CSecretChatDlg::MessagePackageToText(MessagePackage &package)//将消息包转化成明文
{
MessageDollop *pDollop;
__DWORD128 b1, b2;
BOOL bMessagePackageID = TRUE; //只要有一个数字标识不合就永远不能给m_receive_digital_ID合
int quotient, remainder, i;
CSecretKeyEdit secretKeyEditDlg; //只为了转换时间格式
quotient = (package.n * 2) / sizeof(MessageDollop);
remainder = (package.n * 2) % sizeof(MessageDollop);
quotient = remainder?++quotient:quotient;//quotient代表有几个消息块
pDollop = new MessageDollop[quotient]; //消息块是消息包的元素
m_receive_message_dollop_ID.Nil();
for(i = 0;i < quotient;i++)
{
//把消息包分成若干块
::MoveMemory(
(char *)&pDollop[i], //目标
package.data + i * sizeof(MessageDollop),//源内容
sizeof(MessageDollop));
//获得正文内容
::MoveMemory(
m_receive_text + i * sizeof(MessageDollop) / 2,
pDollop[i].text,
sizeof(MessageDollop) / 2);//除2是因为只要得到正文信息
//获得数字标识
if(bMessagePackageID)
{
b1.Load(pDollop[i].digital_ID); //对方签名的数字标识
b2.DigitalID();
if(!(b1 == b2))//只要有一个消息块不合,就不能使得m_messagePackageID合格
{
bMessagePackageID = FALSE;
}
m_receive_digital_ID = b1;
}
//获得消息包的ID
b1.Load(pDollop[i].messageDollop_ID/*每个消息块的ID*/);
m_receive_message_dollop_ID = m_receive_message_dollop_ID + b1;
}
//获得整个消息包的ID
m_receive_message_package_ID.Load(pDollop[0].messagePackage_ID/*消息包的ID*/);
//获得消息发送的时间
m_receive_time = secretKeyEditDlg.CharToCString(pDollop[0].time, 20);
//获取正文的长度
m_receive_text_length = package.n;
delete[] pDollop;
}
CString CSecretChatDlg::GetUserName() //获得通信的用户名
{
CString fileName =
m_appName
+ "\\user\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey");
CFile file;
SecretKey secretKey;
if(!file.Open(
fileName,
CFile::modeReadWrite | CFile::typeBinary))
return "";
if(file.GetLength() != sizeof(SecretKey))
return "";
file.SeekToBegin();
file.Read(&secretKey, sizeof(SecretKey));
file.Close();
if(secretKey.ID != SECRETKEY_ID)
return "";
if(secretKey.privateOrPublic != SECRETKEY_PRIVATE)
return "";
return secretKey.userName;
}
CString CSecretChatDlg::GetFriendName() //获得通信的好友名
{
CString fileName =
m_appName
+ "\\friend\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey");
CFile file;
SecretKey secretKey;
if(!file.Open(
fileName,
CFile::modeReadWrite | CFile::typeBinary))
return "";
if(file.GetLength() != sizeof(SecretKey))
return "";
file.SeekToBegin();
file.Read(&secretKey, sizeof(SecretKey));
file.Close();
if(secretKey.ID != SECRETKEY_ID)
return "";
if(secretKey.privateOrPublic != SECRETKEY_PUBLIC)
return "";
return secretKey.userName;
}
void CSecretChatDlg::send_or_receive_tip(BOOL sendOrReceive)//发送和收到消息提示信息和处理
{
CString nowMessage; //现在获得的信息
CFileFind find; //查找文件用
CFile file;
CString fileName; //消息记录文件名
if(sendOrReceive)
{ //发送
nowMessage =
"("
+
m_send_time
+ ")\t"
+ GetUserName()
+ "\r\n"
+ m_message
+ "\r\n";
m_messageNote += nowMessage;
m_statusMessages.SetWindowText("发送消息");
m_messageNoteEdit.SetWindowText(m_messageNote);
//将消息记录框滚动到最尾
m_messageNoteEdit.LineScroll(m_messageNoteEdit.GetLineCount());
m_messageEdit.SetWindowText("");
//焦点再回到消息输入框
m_messageEdit.SetFocus();
PlayWaveSound(IDR_MESSAGESEND);
}
else
{
CSecretKeyEdit secretKeyEditDlg; //只为了转换密文格式
nowMessage =
"("
+ m_receive_time
+ ")\t"
+ GetFriendName()
+ "\r\n"
+ secretKeyEditDlg.CharToCString(m_receive_text, m_receive_text_length)
+ "\r\n";
m_mes
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -