⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csp.cpp

📁 这个工程主要是非对称的密钥的导出和导入 还有就是会话密钥的操作.
💻 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 + -