?? csp.cpp
字號:
// Csp.cpp: implementation of the CCsp class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CSPTEST2.h"
#include "Csp.h"
#include "wincrypt.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCsp::CCsp()
{
}
CCsp::~CCsp()
{
}
/*************************************************************************
+方法名稱:產生并導出會話密鑰
+輸入參數: BYTE *pbContainer 容器名
+ BYTE *pbPubKey 公鑰數據
+ DWORD dwPubLen 公鑰數據長度
+ BYTE *pbSessionKey 會話密鑰數據
+ DWORD &dwSessionLen 會話密鑰數據長度
+返回值: 0 成功
+其他說明:
*************************************************************************/
int CCsp::GenSessionKey(BYTE *pbContainer, BYTE *pbPubKey, DWORD dwPubLen,
BYTE *pbSessionKey, DWORD *pdwSessionLen)
{
HCRYPTPROV hProv;
HCRYPTKEY hKey;
HCRYPTKEY hSessionKey;
CryptAcquireContext(&hProv, (char *)pbContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(!CryptAcquireContext(&hProv, (char *)pbContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
return -1;
int r = CryptImportKey(hProv, pbPubKey, dwPubLen, 0, 0, &hKey);
if(!r)
{
ReportError("GenSessionKey", "導入保護公鑰失敗!", -2);
if(hProv)
CryptReleaseContext(hProv, 0);
return -2;
}
//產生會話密鑰
r = CryptGenKey(hProv, CALG_3DES, CRYPT_EXPORTABLE, &hSessionKey);
if(!r)
{
ReportError("GenSessionKey", "產生會話密鑰失敗!", -3);
if(hProv)
CryptReleaseContext(hProv, 0);
if(hKey)
CryptDestroyKey(hKey);
return -3;
}
//獲得會話密鑰長度
r = CryptExportKey(hSessionKey, hKey, SIMPLEBLOB, NULL, NULL, pdwSessionLen);
if(!r)
{
ReportError("GenSessionKey", "獲得會話密鑰長度失敗!", -4);
if(hProv)
CryptReleaseContext(hProv, 0);
if(hKey)
CryptDestroyKey(hKey);
if(hSessionKey)
CryptDestroyKey(hSessionKey);
return -4;
}
//導出會話密鑰
r = CryptExportKey(hSessionKey, hKey, SIMPLEBLOB, NULL, pbSessionKey, pdwSessionLen);
if(!r)
{
ReportError("GenSessionKey", "獲得會話密鑰數據失敗!", -5);
if(hProv)
CryptReleaseContext(hProv, 0);
if(hKey)
CryptDestroyKey(hKey);
if(hSessionKey)
CryptDestroyKey(hSessionKey);
return -5;
}
if(hProv)
CryptReleaseContext(hProv, 0);
if(hKey)
CryptDestroyKey(hKey);
if(hSessionKey)
CryptDestroyKey(hSessionKey);
return 0;
}
/*************************************************************************
+方法名稱:產生RSA密鑰對并導出公鑰私鑰數據
+輸入參數: int nKeyFlag 密鑰對類型 1 為簽名密鑰對 2 為加密密鑰對
+ BYTE *pbPubKey 公鑰數據(加密公鑰文件.txt 簽名公鑰文件.txt)
+ DWORD dwPubKeyLen 公鑰數據長度
+ BYTE *pbPriKey 私鑰數據(加密私鑰文件.txt 簽名私鑰文件.txt)
+ DWORD &dwSessionLen 會話密鑰數據長度
+返回值: 0 成功
+其他說明:
*************************************************************************/
int CCsp::GenRsaKeyPairs(int nKeyFlag, BYTE *pbPubKey, DWORD &dwPubKeyLen,
BYTE *pbPriKey, DWORD &dwPriKeyLen)
{
HCRYPTPROV hProv;
HCRYPTKEY hKey;
CryptAcquireContext(&hProv, "RSA", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(!CryptAcquireContext(&hProv, "RSA", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
return -1;
if(nKeyFlag == 1)
{
if(!CryptGenKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKey))
{
//刪除容器 釋放上下文
ReportError("GenRsaKeyPairs", "產生RSA簽名密鑰對失敗!", -2);
CryptAcquireContext(&hProv, "RSA", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(hProv)
CryptReleaseContext(hProv, 0);
return -2;
}
}
else if(nKeyFlag == 2)
{
if(!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey))
{
//刪除容器 釋放上下文
ReportError("GenRsaKeyPairs", "產生RSA簽名密鑰對失敗!", -3);
CryptAcquireContext(&hProv, "RSA", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(hProv)
CryptReleaseContext(hProv, 0);
return -3;
}
}
else
{
CryptAcquireContext(&hProv, "RSA", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(hProv)
CryptReleaseContext(hProv, 0);
return -4;
}
//導出私鑰
DWORD dwTempPriLen;
int r = CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, NULL, NULL, &dwTempPriLen);
if(!r)
{
ReportError("GenRsaKeyPairs", "導出私鑰長度失敗!", -5);
CryptAcquireContext(&hProv, "RSA", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(hProv)
CryptReleaseContext(hProv, 0);
return -5;
}
BYTE *pbTempPriData = (BYTE *)malloc(dwTempPriLen+1);
r = CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, NULL, pbTempPriData, &dwTempPriLen);
if(!r)
{
ReportError("GenRsaKeyPairs", "導出私鑰數據失敗!", -6);
CryptAcquireContext(&hProv, "RSA", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(hProv)
CryptReleaseContext(hProv, 0);
return -6;
}
//導出公鑰
DWORD dwTempPubLen;
r = CryptExportKey(hKey, NULL, PUBLICKEYBLOB, NULL, NULL, &dwTempPubLen);
if(!r)
{
ReportError("GenRsaKeyPairs", "導出公鑰長度失敗!", -7);
CryptAcquireContext(&hProv, "RSA", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(hProv)
CryptReleaseContext(hProv, 0);
return -7;
}
BYTE *pbTempPubData = (BYTE *)malloc(dwTempPubLen+1);
r = CryptExportKey(hKey, NULL, PUBLICKEYBLOB, NULL, pbTempPubData, &dwTempPubLen);
if(!r)
{
ReportError("GenRsaKeyPairs", "導出公鑰數據失敗!", -8);
CryptAcquireContext(&hProv, "RSA", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(hProv)
CryptReleaseContext(hProv, 0);
return -8;
}
//緩沖區拷貝
memcpy(pbPriKey, pbTempPriData, dwTempPriLen); //拷貝私鑰數據
dwPubKeyLen = dwTempPubLen; //私鑰數據長度
memcpy(pbPubKey, pbTempPubData, dwTempPubLen); //拷貝公鑰數據
dwPriKeyLen = dwTempPriLen; //公鑰長度
//刪除容器
CryptAcquireContext(&hProv, "RSA", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
//釋放內存
if(pbTempPriData)
free(pbTempPriData);
if(pbTempPubData)
free(pbTempPubData);
if(hProv)
CryptReleaseContext(hProv, 0);
return 0;
}
void CCsp::ReportError(CString strFunName, CString strErrorDescript, int nErrorNo)
{
m_strError.Format("出錯函數%s:出錯描述%s:出錯代碼%d", strFunName, strErrorDescript, nErrorNo);
return;
}
/*************************************************************************
+方法名稱:導入公鑰數據
+輸入參數: CString strContainer 容器名稱
+ BYTE *pbPubKey 公鑰數據(加密公鑰文件.txt 簽名公鑰文件.txt)
+ DWORD dwPubLen 公鑰數據長度
+返回值: 0 成功
+其他說明:
*************************************************************************/
int CCsp::ImportPubKey(CString strContainer, BYTE *pbPubKey, DWORD dwPubLen)
{
HCRYPTPROV hProv;
HCRYPTKEY hKey;
CryptAcquireContext(&hProv, strContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(!CryptAcquireContext(&hProv, strContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
return -1;
//導入公鑰數據
int r = CryptImportKey(hProv, pbPubKey, dwPubLen, NULL, NULL, &hKey);
if(!r)
{
ReportError("ImportPubKey", "導入公鑰數據失敗!", -2);
if(hProv)
CryptReleaseContext(hProv, 0);
return -2;
}
if(hProv)
CryptReleaseContext(hProv, 0);
return 0;
}
/*************************************************************************
+方法名稱:導入私鑰數據
+輸入參數: CString strContainer 容器名稱
+ BYTE *pbPriKey 私鑰數據(加密私鑰文件.txt 簽名私鑰文件.txt)
+ DWORD dwPriLen 私鑰數據長度
+返回值: 0 成功
+其他說明:
*************************************************************************/
int CCsp::ImportPriKey(CString strContainer, BYTE *pbPriKey, DWORD dwPriLen)
{
HCRYPTPROV hProv;
HCRYPTKEY hKey;
CryptAcquireContext(&hProv, strContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(!CryptAcquireContext(&hProv, strContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
return -1;
//導入私鑰數據
int r = CryptImportKey(hProv, pbPriKey, dwPriLen, NULL, NULL, &hKey);
if(!r)
{
ReportError("ImportPriKey", "導入私鑰數據失敗!", -2);
if(hProv)
CryptReleaseContext(hProv, 0);
return -2;
}
if(hProv)
CryptReleaseContext(hProv, 0);
return 0;
}
/*************************************************************************
+方法名稱:會話加密數據
+輸入參數: BYTE *pbSessionKey 會話密鑰數據 (會話密鑰數據文件.txt)
+ DWORD dwSessionLen 會話密鑰長度
+ BYTE *pbSourceData 待加密數據 (會話加密原文.txt)
+ DWORD dwSourceLen 待加密數據長度
+ BYTE *pbPriKey 解密私鑰數據 (加密私鑰文件.txt)
+ DWORD dwPriLen 解密私鑰數據長度
+ BYTE *pbDestData 加密后數據 (會話數據加密密文.txt)
+ DWORD &dwDestLen 加密后數據長度
+ CString strContainer 容器名稱
+返回值: 0 成功
+其他說明:
*************************************************************************/
int CCsp::SessionEncrypt(BYTE *pbSessionKey, DWORD dwSessionLen,
BYTE *pbSourceData, DWORD dwSourceLen,
BYTE *pbPriKey, DWORD dwPriLen,
BYTE *pbDestData,DWORD *pdwDestLen,
BYTE *pbContainer)
{
HCRYPTPROV hProv;
HCRYPTKEY hSessionKey;
HCRYPTKEY hKey;
CryptAcquireContext(&hProv, (char *)pbContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(!CryptAcquireContext(&hProv, (char *)pbContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
return -1;
//導入私鑰到容器中
int r = CryptImportKey(hProv, pbPriKey, dwPriLen, 0, NULL, &hKey);
if(!r)
{
ReportError("SessionEncrypt", "導入會話解密私鑰失敗!", -2);
if(hProv)
CryptReleaseContext(hProv, 0);
return -2;
}
r = CryptImportKey(hProv, pbSessionKey, dwSessionLen, hKey, NULL, &hSessionKey);
if(!r)
{
ReportError("SessionEncrypt", "導入會話密鑰失敗!", -3);
if(hProv)
CryptReleaseContext(hProv, 0);
if(hKey)
CryptDestroyKey(hKey);
return -3;
}
r = CryptEncrypt(hSessionKey, NULL, TRUE, NULL, pbSourceData, &dwSourceLen,
dwSourceLen+256);
if(!r)
{
ReportError("SessionEncrypt", "加密數據失敗!", -4);
if(hProv)
CryptReleaseContext(hProv, 0);
if(hKey)
CryptDestroyKey(hKey);
if(hSessionKey)
CryptDestroyKey(hSessionKey);
return -4;
}
*pdwDestLen = dwSourceLen;
memcpy(pbDestData, pbSourceData, dwSourceLen);
if(hProv)
CryptReleaseContext(hProv, 0);
if(hSessionKey)
CryptDestroyKey(hSessionKey);
if(hKey)
CryptDestroyKey(hKey);
return 0;
}
/*************************************************************************
+方法名稱:會話解密數據
+輸入參數: BYTE *pbSessionKey 會話密鑰數據 (會話密鑰數據文件.txt)
+ DWORD dwSessionLen 會話密鑰長度
+ BYTE *pbSourceData 待解密數據 (會話數據加密密文.txt)
+ DWORD dwSourceLen 待解密數據長度
+ BYTE *pbPriKey 解密私鑰數據 (加密私鑰文件.txt)
+ DWORD dwPriLen 解密私鑰數據長度
+ BYTE *pbDestData 解密后數據 (會話解密后數據.txt)
+ DWORD &dwDestLen 解密后數據長度
+ CString strContainer 容器名稱
+返回值: 0 成功
+其他說明:
*************************************************************************/
int CCsp::SessionDecrypt(BYTE *pbSessionKey, DWORD dwSessionLen,
BYTE *pbSourceData, DWORD dwSourceLen,
BYTE *pbPriKey, DWORD dwPriLen,
BYTE *pbDestData, DWORD *pdwDestLen,
BYTE *pbContainer)
{
HCRYPTPROV hProv;
HCRYPTKEY hKey;
HCRYPTKEY hSessionKey;
CryptAcquireContext(&hProv, (char *)pbContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
if(!CryptAcquireContext(&hProv, (char *)pbContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
return -1;
//導入私鑰到容器中
int r = CryptImportKey(hProv, pbPriKey, dwPriLen, 0, NULL, &hKey);
if(!r)
{
ReportError("SessionEncrypt", "導入會話解密私鑰失敗!", -2);
if(hProv)
CryptReleaseContext(hProv, 0);
return -2;
}
r = CryptImportKey(hProv, pbSessionKey, dwSessionLen, hKey, NULL, &hSessionKey);
if(!r)
{
ReportError("SessionEncrypt", "導入會話密鑰失敗!", -3);
if(hProv)
CryptReleaseContext(hProv, 0);
if(hKey)
CryptDestroyKey(hKey);
return -3;
}
r = CryptDecrypt(hSessionKey, NULL, TRUE, NULL, pbSourceData, &dwSourceLen);
if(!r)
{
ReportError("SessionEncrypt", "會話解密數據失敗!", -4);
if(hProv)
CryptReleaseContext(hProv, 0);
if(hKey)
CryptDestroyKey(hKey);
if(hSessionKey)
CryptDestroyKey(hSessionKey);
return -4;
}
*pdwDestLen = dwSourceLen;
memcpy(pbDestData, pbSourceData, *pdwDestLen);
if(hProv)
CryptReleaseContext(hProv, 0);
if(hSessionKey)
CryptDestroyKey(hSessionKey);
if(hKey)
CryptDestroyKey(hKey);
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -