📄 secretkeyedit.cpp
字号:
// SecretKeyEdit.cpp : implementation file
//
#include "stdafx.h"
#include "secretchat.h"
#include "SecretKeyEdit.h"
#include "RSA.h"
#include "SecretChatDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSecretKeyEdit dialog
CSecretKeyEdit::CSecretKeyEdit(CWnd* pParent /*=NULL*/)
: CDialog(CSecretKeyEdit::IDD, pParent)
{
//{{AFX_DATA_INIT(CSecretKeyEdit)
m_email = _T("");
m_qq = _T("");
m_userName = _T("");
m_secretKeyEdit = _T("");
//}}AFX_DATA_INIT
}
void CSecretKeyEdit::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSecretKeyEdit)
DDX_Text(pDX, IDC_EMAIL, m_email);
DDV_MaxChars(pDX, m_email, 32);
DDX_Text(pDX, IDC_QQ, m_qq);
DDV_MaxChars(pDX, m_qq, 32);
DDX_Text(pDX, IDC_USERNAME, m_userName);
DDV_MaxChars(pDX, m_userName, 32);
DDX_Text(pDX, IDC_SECRETKEY, m_secretKeyEdit);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSecretKeyEdit, CDialog)
//{{AFX_MSG_MAP(CSecretKeyEdit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSecretKeyEdit message handlers
DWORD WINAPI create_secret_key_thread(LPVOID param) //创建密钥线程函数
{
CSecretKeyEdit * pKey = (CSecretKeyEdit *)param;
//查看文件是否存在
CFileFind find;
if( find.FindFile(pKey->m_user_private_key_file_name) )
{
//提示文件存在并退出
MessageBox(
NULL,
"文件已经存在",
"生成私钥文件",
MB_ICONEXCLAMATION);
pKey->SetWindowText("创建新的用户密钥");
pKey->m_bCreate = TRUE; //能再创建
return 0;
}
//生成密钥和用户信息
private_key key;
key.create();
key.vlong_to_SK(pKey->m_secretKey.sk);
key.vlong_to_PK(pKey->m_secretKey.pk);
pKey->CStringToChar(
pKey->m_secretKey.userName,
pKey->m_userName,
32);
pKey->CStringToChar(
pKey->m_secretKey.qq,
pKey->m_qq,
32);
pKey->CStringToChar(
pKey->m_secretKey.email,
pKey->m_email,
32);
pKey->m_secretKey.version = SECRETKEY_VERSION;
pKey->m_secretKey.privateOrPublic = SECRETKEY_PRIVATE;
pKey->m_secretKey.ID = SECRETKEY_ID;
//把密钥信息写入文件,私钥文件
CFile file;
file.Open(
pKey->m_user_private_key_file_name,
CFile::modeCreate | CFile::modeReadWrite | CFile::typeBinary);
file.Write(
&pKey->m_secretKey,
sizeof(SecretKey)); //写入信息
file.Close();
//把密钥信息写入文件,公钥文件
pKey->CreatePublicKey(pKey->m_user_private_key_file_name);
//提示成功
MessageBox(
NULL,
"已经生成密钥,可以安全的进行通讯。",
"密聊",
MB_ICONINFORMATION);
//更新列表,如果没m_publicKeyManagerDlg窗口就会出错
//pSecretChatDlg->m_setupDlg.ShowTabWindow(1);
pKey->m_bCreate = TRUE; //可以再创建
pKey->SetWindowText("创建新的用户密钥");
return 0;
}
void CSecretKeyEdit::OnOK()
{
if(!m_bCreate)
{
MessageBox(
"创建密钥中",
"密聊",
MB_ICONINFORMATION);
return;
}
CSecretChatDlg * pSecretChatDlg = (CSecretChatDlg *)AfxGetMainWnd();
if(!UpdateData()) return;
CEdit *pTemp;
if(m_userName == "")
{
pTemp = (CEdit *)GetDlgItem(IDC_USERNAME);
pTemp->SetFocus();
//不能为空
MessageBox(
"不能为空",
"warning",
MB_ICONEXCLAMATION);
return;
}
else if(m_qq == "")
{
pTemp = (CEdit *)GetDlgItem(IDC_QQ);
pTemp->SetFocus();
//不能为空
MessageBox(
"不能为空",
"warning",
MB_ICONEXCLAMATION);
return;
}
else if(m_email == "")
{
pTemp = (CEdit *)GetDlgItem(IDC_EMAIL);
pTemp->SetFocus();
//不能为空
MessageBox(
"不能为空",
"warning",
MB_ICONEXCLAMATION);
return;
}
if(m_select == SELECT_CREATE)
{
SetWindowText("创建新的用户密钥 (正在创建中)");
m_user_private_key_file_name =
pSecretChatDlg->m_appName + "\\user\\" + m_userName + ".sk";
m_bCreate = FALSE; //不能再创建
unsigned long nThreadID;
::CreateThread(
NULL,
0,
create_secret_key_thread,
this,
0,
&nThreadID);
return;
}
else //SELECT_PRIVATE和SELECT_PUBLIC的处理相同
{
CStringToChar(
m_secretKey.qq,
m_qq,
32);
CStringToChar(
m_secretKey.email,
m_email,
32);
//更改密钥信息写入私钥文件
CFile file;
file.Open(
m_fileName,//密钥的文件全路径
CFile::modeReadWrite | CFile::typeBinary);
file.SeekToBegin();
file.Write(
&m_secretKey,
sizeof(SecretKey)); //写入信息
file.Close();
}
CDialog::OnOK();
}
void CSecretKeyEdit::OnCancel()
{
if(!m_bCreate)
{
MessageBox(
"创建密钥中",
"密聊",
MB_ICONINFORMATION);
return;
}
CDialog::OnCancel();
}
BOOL CSecretKeyEdit::OnInitDialog()
{
CDialog::OnInitDialog();
CEdit *pUserName = (CEdit *)GetDlgItem(IDC_USERNAME);
CStatic *pSecretKeyStatic = (CStatic *)GetDlgItem(IDC_SECRETKEYSTATIC);
CButton *pOK = (CButton *)GetDlgItem(IDOK);
CEdit *psecretKey = (CEdit *)GetDlgItem(IDC_SECRETKEY);
if(m_select == SELECT_CREATE)
{
pSecretKeyStatic->SetWindowText("生成密钥说明:");
pUserName->SetReadOnly(FALSE);
SetWindowText("创建新的用户密钥");
pOK->SetWindowText("生成");
CString str;
str.LoadString(IDS_CREATEPUBLICKEYHELP);
psecretKey->SetWindowText(str);
//psecretKey->SetWindowText(" \"密聊\"采用 2048bit 的 RSA 数据加密算法对数据进行加密和数字签名,在使用前必须生成用户的私钥和公钥。\r\n 只要通过安全通道相互把公钥传递给通讯方后,彼此就可以进行安全的通话和身份验证了。\r\n 生成私有密钥文件 [用户名.sk] 和公开密钥文件 [用户名.pk] 的过程需要稍等几分钟...");
}
else if(m_select == SELECT_PRIVATE)
{
pSecretKeyStatic->SetWindowText("私钥信息(2048bit):");
pUserName->SetReadOnly();
SetWindowText("用户私钥编辑");
pOK->SetWindowText("更改");
}
else if(m_select == SELECT_PUBLIC)
{
pSecretKeyStatic->SetWindowText("公钥信息(2048bit):");
pUserName->SetReadOnly();
SetWindowText("好友公钥编辑");
pOK->SetWindowText("更改");
}
m_bCreate = TRUE; //可以再创建
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
CString CSecretKeyEdit::CharToHexToString(char m) //把一个字符转换成十六进制再用字符表示
{
char hex;
CString strHex;
//左边4位的表示
hex = m & (char)0xf0;
hex = hex >> 4;
hex = hex & (char)0xf; //有时被移进来的为会为1
switch(hex)
{
case 0:
strHex = "0";
break;
case 1:
strHex = "1";
break;
case 2:
strHex = "2";
break;
case 3:
strHex = "3";
break;
case 4:
strHex = "4";
break;
case 5:
strHex = "5";
break;
case 6:
strHex = "6";
break;
case 7:
strHex = "7";
break;
case 8:
strHex = "8";
break;
case 9:
strHex = "9";
break;
case 10:
strHex = "A";
break;
case 11:
strHex = "B";
break;
case 12:
strHex = "C";
break;
case 13:
strHex = "D";
break;
case 14:
strHex = "E";
break;
case 15:
strHex = "F";
break;
}
//右边4位的表示
hex = m & (char)0xf;
switch(hex)
{
case 0:
strHex += "0";
break;
case 1:
strHex += "1";
break;
case 2:
strHex += "2";
break;
case 3:
strHex += "3";
break;
case 4:
strHex += "4";
break;
case 5:
strHex += "5";
break;
case 6:
strHex += "6";
break;
case 7:
strHex += "7";
break;
case 8:
strHex += "8";
break;
case 9:
strHex += "9";
break;
case 10:
strHex += "A";
break;
case 11:
strHex += "B";
break;
case 12:
strHex += "C";
break;
case 13:
strHex += "D";
break;
case 14:
strHex += "E";
break;
case 15:
strHex += "F";
break;
}
return strHex;
}
int CSecretKeyEdit::validateSecretKey(CString fileName)
{ //验证是不是密钥文件(私钥为1,公钥为2,都不是为0)
m_fileName = fileName;
CFile file;
if(!file.Open(
fileName,
CFile::modeReadWrite | CFile::typeBinary))
return 0;
if(file.GetLength() != sizeof(SecretKey))
return 0;
file.SeekToBegin();
file.Read(&m_secretKey, sizeof(SecretKey));
file.Close();
if(m_secretKey.ID != SECRETKEY_ID)
return 0;
m_userName = CharToCString(m_secretKey.userName, 32);
m_qq = CharToCString(m_secretKey.qq, 32);
m_email = CharToCString(m_secretKey.email, 32);
char chTemp[2048 / 8];
if(m_secretKey.privateOrPublic == SECRETKEY_PRIVATE)
{
::MoveMemory(
chTemp, //目标
(char *)&m_secretKey.sk, //源内容
2048 / 8);
}
else
{
::MoveMemory(
chTemp, //目标
(char *)&m_secretKey.pk, //源内容
2048 / 8);
}
//将密钥换成二进制显示
m_secretKeyEdit = "";
for(int i = 0;i < 256;i++)
{
m_secretKeyEdit += CharToHexToString(chTemp[i]) + " ";
if(!(i == 0 || i == 255))
{
if((i + 1) % 16 == 0)
m_secretKeyEdit += "\r\n";
}
}
return m_secretKey.privateOrPublic;
}
void CSecretKeyEdit::CStringToChar(char *ch, CString str,int n)
{ //字符串转到字符数组
for( int i = 0;i < str.GetLength();i++)
{
if( i == n) return;
ch[i] = str[i];
}
if( i == n) return; //为了使数组char[n]不越界,才要这样做的
ch[i] = NULL;
}
CString CSecretKeyEdit::CharToCString(char *ch, int n/*char数组的大小*/)
{ ////字符数组转到字符串
CString str;
char * pbuf = new char[n + 1];
pbuf[n] = NULL;
for( int i = 0;i < n;i++)
pbuf[i] = ch[i];
str = pbuf;
delete[] pbuf;
return str;
}
BOOL CSecretKeyEdit::CreatePublicKey(CString fileName) //生成公钥
{
SecretKey secretKey;
CFile file;
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();
//私钥文件名要转换成对应的公钥文件名
fileName.SetAt(
fileName.GetLength() - 2,
'p');
//把密钥信息写入文件,公钥文件
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;
//查看文件是否存在
WIN32_FIND_DATA wfd;
HANDLE hSearch = ::FindFirstFile(
fileName,//密钥的文件全路径
&wfd);
if( hSearch != INVALID_HANDLE_VALUE) //文件存在
{
//提示文件存在并退出
if(MessageBox(
"文件已经存在。覆盖 " + fileName + " 文件吗?",
"生成公钥文件",
MB_YESNO | MB_ICONQUESTION) == IDNO)
{
return FALSE;
}
}
file.Open(
fileName,//密钥的文件全路径
CFile::modeCreate | CFile::modeReadWrite | CFile::typeBinary);
file.Write(
&secretKey,
sizeof(SecretKey)); //写入信息
file.Close();
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -