?? 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 + -