📄 veridlg.cpp
字号:
// VeriDlg.cpp : implementation file
//
#include "stdafx.h"
#include "PKI.h"
#include "PKIDlg.h"
#include "VeriDlg.h"
#include "SetDlg.h"
#include <stdio.h>
#define _WIN32_WINNT 0x0400
#include <windows.h>
#include <wincrypt.h>
#define ENCRYPT_BLOCK_SIZE 8
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CVeriDlg dialog
CVeriDlg::CVeriDlg(CWnd* pParent /*=NULL*/)
: CDialog(CVeriDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CVeriDlg)
m_file_veri = _T("");
m_letter_veri = _T("");
m_pkey_veri = _T("");
m_signed_veri = _T("");
m_state_veri = _T("");
//}}AFX_DATA_INIT
m_alg_id_veri=CALG_RC4;
m_hash_veri=CALG_MD5;
m_prov_veri=PROV_RSA_FULL;
}
void CVeriDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVeriDlg)
DDX_Text(pDX, IDC_FILE_VERI_EDIT, m_file_veri);
DDX_Text(pDX, IDC_LETTER_VERI_EDIT, m_letter_veri);
DDX_Text(pDX, IDC_PKEY_VERI_EDIT, m_pkey_veri);
DDX_Text(pDX, IDC_SIGNED_VERI_EDIT, m_signed_veri);
DDX_Text(pDX, IDC_STATE_VERY_STATIC, m_state_veri);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CVeriDlg, CDialog)
//{{AFX_MSG_MAP(CVeriDlg)
ON_BN_CLICKED(IDC_VERI_BUTTON, OnVeriButton)
ON_BN_CLICKED(IDC_LETTER_VERI_BUTTON, OnLetterVeriButton)
ON_BN_CLICKED(IDC_PUB_KEY_VERI_BUTTON, OnPubKeyVeriButton)
ON_BN_CLICKED(IDC_SIGN_FILE_VERI_BUTTON, OnSignFileVeriButton)
ON_BN_CLICKED(IDC_FILE_VERI_BUTTON, OnFileVeriButton)
ON_BN_CLICKED(IDC_YUANWEN_FILE_BUTTON, OnYuanwenFileButton)
ON_BN_CLICKED(IDC_LET_BUTTON, OnLetButton)
ON_BN_CLICKED(IDC_SET_VERI_BUTTON, OnSetVeriButton)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVeriDlg message handlers
CString MyHandleError2(char *s)
{
CString str;
str.Format("程序运行时发生错误. \n错误代码: %x.\n", GetLastError());
str+=s;
AfxMessageBox(str);
return str;
}
void CVeriDlg::OnVeriButton()
{
// TODO: Add your control notification handler code her
HCRYPTPROV hProv;
HCRYPTKEY hPubKey;
BYTE *pbKeyBlob;
DWORD dwBlobLen;
HCRYPTHASH hHash;
BYTE *pbSignature; //数字签名
DWORD dwSigLen;
LPTSTR szDescription = "";
UpdateData(TRUE);
m_state_veri="";
//--------------------------------------------------------------------
// 获得CSP句柄,密钥容器名为登陆用户名
if(CryptAcquireContext(
&hProv,
NULL,
NULL,
PROV_RSA_FULL,
0))
{
m_state_veri+="已获取CSP,秘钥生成算法:"+GetProvType(m_prov_veri)+"\n";
}
else
//密钥容器不存在创建之
{
if(CryptAcquireContext(
&hProv,
NULL,
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
m_state_veri+="已创建一个新的密钥容器秘钥生成算法:"+GetProvType(m_prov_veri)+"\n";
else
{ m_state_veri+=MyHandleError2("在获取密钥容器时发生错误,退出\n");UpdateData(FALSE);return;}
}
CFile signdatafile,yuanwenfile,pubkeyfile;
if(m_pkey_veri==""||!pubkeyfile.Open(m_pkey_veri,CFile::modeReadWrite))
{
MessageBox("请选择正确的公钥文件!");return;
}
if(m_file_veri==""||!yuanwenfile.Open(m_file_veri,CFile::modeReadWrite))
{
MessageBox("请选择正确的原文件!");return;
}
if(m_signed_veri==""||!signdatafile.Open(m_signed_veri,CFile::modeReadWrite))
{
MessageBox("请选择正确的签名文件!");return;
}
dwBlobLen=pubkeyfile.GetLength();
pbKeyBlob=(BYTE *)malloc(dwBlobLen);
pubkeyfile.Read(pbKeyBlob,dwBlobLen);
if(CryptImportKey(
hProv,
pbKeyBlob,
dwBlobLen,
0,
0,
&hPubKey))
m_state_veri+="公钥已经成功导入!\n\n";
else
{
m_state_veri+=MyHandleError2("公钥导出出错.\n");UpdateData(FALSE);return;
}
//--------------------------------------------------------------------
// 创建哈希对象
if(CryptCreateHash(
hProv,
m_hash_veri,//CALG_MD5,
0,
0,
&hHash))
m_state_veri+="已经获取hash对象,hash算法"+GetHashType(m_hash_veri)+"\n\n";
else
{
m_state_veri+=MyHandleError2("创建hash对象时出错,退出");UpdateData(FALSE);return;
}
//--------------------------------------------------------------------
// 跟生成时一样对数据进行hash运算
BYTE *pbBuffer;
pbBuffer=(BYTE *)malloc(yuanwenfile.GetLength());
yuanwenfile.Read(pbBuffer,yuanwenfile.GetLength());
DWORD dwBufferLen = yuanwenfile.GetLength();
pbSignature=(BYTE *)malloc(signdatafile.GetLength());
signdatafile.Read(pbSignature,signdatafile.GetLength());
dwSigLen = signdatafile.GetLength();
if(CryptHashData(
hHash,
pbBuffer,
dwBufferLen,
0))
m_state_veri+="对数据hash运算成功!\n\n";
else
{
m_state_veri+=MyHandleError2("对数据进行hash运算出错,退出");UpdateData(FALSE);return;
}
//--------------------------------------------------------------------
// 验证数字签名
if(CryptVerifySignature(
hHash,
pbSignature, //数字签名数据
dwSigLen,
hPubKey, //签名者的公钥
szDescription,
0))
{
MessageBox("恭喜:是正确的数字签名!");
m_state_veri+="恭喜:是正确的数字签名!";
}
else
{
MessageBox("错误:签名是错误的\n");
m_state_veri+="错误:签名是错误的\n请检查参数是否设置正确,若正确则请联系发送方";
}
UpdateData(FALSE);
//--------------------------------------------------------------------
// Free memory to be used to store signature.
if(pbSignature)
free(pbSignature);
if(pbKeyBlob)
free(pbKeyBlob);
//--------------------------------------------------------------------
// Destroy the hash object.
if(hHash)
CryptDestroyHash(hHash);
//--------------------------------------------------------------------
// Release the provider handle.
if(hProv)
CryptReleaseContext(hProv, 0);
signdatafile.Close(),yuanwenfile.Close(),pubkeyfile.Close();
}
void CVeriDlg::OnLetterVeriButton()
{
// TODO: Add your control notification handler code here
CFileDialog dlg(TRUE,NULL,".\\数字信封",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,NULL,NULL);
if(dlg.DoModal()==IDOK)
{
m_letter_veri=dlg.GetPathName();
}
else m_letter_veri="";
UpdateData(FALSE);
}
void CVeriDlg::OnPubKeyVeriButton()
{
// TODO: Add your control notification handler code here
CFileDialog dlg(TRUE,NULL,".\\公钥",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,NULL,NULL);
if(dlg.DoModal()==IDOK)
{
m_pkey_veri=dlg.GetPathName();
}
else m_pkey_veri="";
UpdateData(FALSE);
}
void CVeriDlg::OnSignFileVeriButton()
{
// TODO: Add your control notification handler code here
CFileDialog dlg(TRUE,NULL,".\\签名后的文件",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,NULL,NULL);
if(dlg.DoModal()==IDOK)
{
m_signed_veri=dlg.GetPathName();
}
else m_signed_veri="";
UpdateData(FALSE);
}
void CVeriDlg::OnFileVeriButton()
{
// TODO: Add your control notification handler code here
}
void CVeriDlg::OnYuanwenFileButton()
{
// TODO: Add your control notification handler code here
CFileDialog dlg(FALSE,NULL,".\\原文.txt",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,NULL,NULL);
if(dlg.DoModal()==IDOK)
{
m_file_veri=dlg.GetPathName();
}
else m_file_veri="";
UpdateData(FALSE);
}
void CVeriDlg::OnLetButton()
{
// TODO: Add your control notification handler code here
FILE *hSource = NULL;
FILE *hDestination = NULL;
INT eof = 0;
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
HCRYPTKEY hXchgKey = 0;
HCRYPTHASH hHash = 0;
PBYTE pbKeyBlob = NULL;
DWORD dwKeyBlobLen;
PBYTE pbBuffer = NULL;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;
CFile letterfile,file;
UpdateData(TRUE);
if(m_letter_veri==""||!letterfile.Open(m_letter_veri,CFile::modeReadWrite))
{
MessageBox("请选择正确的数字信封!");return;
}
if(m_file_veri==""||!file.Open(m_file_veri,CFile::modeCreate|CFile::modeReadWrite))
{
MessageBox("请选择正确的保存文件地址!");return;
}
letterfile.Close();
file.Close();
m_state_veri="";
char *yuanwen,*letter;
int len=m_file_veri.GetLength();
int len2=m_letter_veri.GetLength();
yuanwen=(char *)malloc(len+1);
letter=(char *)malloc(len2+1);
for(int i=0;i<len;i++)
*(yuanwen+i)=m_file_veri[i];
for(i=0;i<len2;i++)
*(letter+i)=m_letter_veri[i];
*(yuanwen+len)='\0';
*(letter+len2)='\0';
hSource = fopen(letter,"rb");// 打开源文件.
hDestination = fopen(yuanwen,"wb") ;
if(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0))
m_state_veri+="已经获取CSP,秘钥生成算法:"+GetProvType(m_prov_veri)+"\n\n";
// 读隐码的长度并分配内存
if(fread(&dwKeyBlobLen, sizeof(DWORD), 1, hSource))
m_state_veri+="已经计算出会话密钥的长度!\n\n";
else
{ m_state_veri+="计算会话密钥长度出错,退出\n\n";UpdateData(FALSE);return;}
if(pbKeyBlob =(BYTE *) malloc(dwKeyBlobLen))
m_state_veri+="为会话密钥分配内存\n";
else{ m_state_veri+="为会话密钥分配内存失败,退出\n\n";UpdateData(FALSE);return;}
// 从源文件中读隐码.
if(fread(pbKeyBlob, 1, dwKeyBlobLen, hSource))
m_state_veri+="已经读入会话密钥!\n\n";
else
{ m_state_veri+="已经读入会话密钥!失败,退出\n\n";UpdateData(FALSE);return;}
// 将隐码输入CSP
if(CryptImportKey(hProv, pbKeyBlob, dwKeyBlobLen, 0, 0, &hKey))
m_state_veri+="已经把会话密钥导入CSP\n\n";
else
{ m_state_veri+="会话密钥导入CSP失败,退出\n\n";UpdateData(FALSE);return;}
dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
if(ENCRYPT_BLOCK_SIZE > 1)
{
dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
}
else
{
dwBufferLen = dwBlockLen;
}
pbBuffer =(BYTE *)malloc(dwBufferLen);
//解密源文件并写入目标文件
do {
dwCount = fread(pbBuffer, 1, dwBlockLen,hSource);
//dwCount=hs.Read(pbBuffer,dwBlockLen);
eof = feof(hSource);
//eof=hs.;
// 解密数据
CryptDecrypt(hKey, 0, eof, 0, pbBuffer, &dwCount);
// 将解密过的数据写入目标文件
fwrite(pbBuffer, 1, dwCount, hDestination);
} while(!feof(hSource));
m_state_veri+="已经解密成功,并且保存在"+m_file_veri+"\n\n";
fclose(hSource);
fclose(hDestination);
MessageBox("解开数字信封成功!");
UpdateData(FALSE);
//MessageBox("OK\n");
}
void CVeriDlg::OnSetVeriButton()
{
// TODO: Add your control notification handler code here
CSetDlg dlg;
GetProvType(m_prov_veri);
dlg.m_prov=m_prov_type;
GetHashType(m_hash_veri);
dlg.m_hash=m_hash_type;
GetSessionType(m_alg_id_veri);
dlg.m_alg_id=m_session_type;
if(IDOK==dlg.DoModal())
{
switch(dlg.m_alg_id)
{
case 0:
m_alg_id_veri=CALG_RC2;break;
case 1:
m_alg_id_veri=CALG_RC4;break;
default:m_alg_id_veri=CALG_RC2;break;
}
switch(dlg.m_hash)
{
case 0:
m_hash_veri=CALG_HMAC;break;
case 1:
m_hash_veri=CALG_MAC;break;
case 2:
m_hash_veri=CALG_MD2;break;
case 3:
m_hash_veri=CALG_MD5;break;
case 4:
m_hash_veri=CALG_SHA;break;
default:m_hash_veri=CALG_MD5;break;
}
switch(dlg.m_prov)
{
case 0:
m_prov_veri=PROV_RSA_FULL;break;
case 1:
m_prov_veri=PROV_RSA_SIG;break;
case 2:
m_prov_veri=PROV_DSS;break;
case 3:
m_prov_veri=PROV_DSS_DH;break;
case 4:
m_prov_veri=PROV_FORTEZZA;break;
case 5:
m_prov_veri=PROV_MS_EXCHANGE;break;
case 6:
m_prov_veri=PROV_RSA_SCHANNEL;break;
case 7:
m_prov_veri=PROV_SSL;break;
default:
m_prov_veri=PROV_RSA_FULL;break;
}
}
}
CString CVeriDlg::GetHashType(unsigned int hash)
{
CString str;
switch(hash)
{
case CALG_HMAC:
str="HMAC";m_hash_type=0;break;
case CALG_MAC:
str="MAC";m_hash_type=1;break;
case CALG_MD2:
str="MD2";m_hash_type=2;break;
case CALG_MD5:
str="MD5";m_hash_type=3;break;
case CALG_SHA:
str="SHA";m_hash_type=4;break;
default:str="MD5";m_hash_type=3;break;
}
return str;
}
CString CVeriDlg::GetSessionType(unsigned int session)
{
CString str;
switch(session)
{
case CALG_RC2:
str="RC2";m_session_type=0;break;
case CALG_RC4:
str="RC4";m_session_type=1;break;
default:str="RC4";m_session_type=1;break;
}
return str;
}
CString CVeriDlg::GetProvType(unsigned int prov)
{
CString str;
switch(prov)
{
case PROV_RSA_FULL:
m_prov_type=0;str="RSA_FULL";break;
case PROV_RSA_SIG:
m_prov_type=1;str="RSA_SIG";break;
case PROV_DSS:
m_prov_type=2;str="DSS";break;
case PROV_DSS_DH:
m_prov_type=3;str="DSS_DH";break;
case PROV_FORTEZZA:
m_prov_type=4;str="FORTEZZA";break;
case PROV_MS_EXCHANGE:
m_prov_type=5;str="MS_EXCHANGE";break;
case PROV_RSA_SCHANNEL:
m_prov_type=6;str="RSA_SCHANNEL";break;
case PROV_SSL:
m_prov_type=7;str="SSL";break;
default:
m_prov_type=0;str="RSA_FULL";break;
}
return str;
}
void CVeriDlg::OnCancel()
{
// TODO: Add extra cleanup here
CPKIDlg dlg;
dlg.DoModal();
CDialog::OnCancel();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -