现在的位置: 首页 > 综合 > 正文

编写ATL工程实现ActiveX控件调用cryptoAPI接口(三)————AES对称加密与解密

2014年12月13日 ⁄ 综合 ⁄ 共 11076字 ⁄ 字号 评论关闭

注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出.

/*
 * 
 * 
 * 文件名称:EncryptAES.cpp
 * 摘    要:
 *		AES对称加密与AES对称解密,生成会话密钥
 * 当前版本:1.0
 * 作    者:周绍禹
 * 创建日期:2012年3月4日
 */
#include "StdAfx.h"
#include "EncryptAES.h"
#include "base64.h"
#include <comdef.h>
#include "generic.h"
#include "Map.h"

/**
*
*初始化CSP
*
*/
CEncryptAES::CEncryptAES():CSP_NAME(MS_ENH_RSA_AES_PROV)
{
	log = new Log("CEncryptAES");
}

CEncryptAES::~CEncryptAES()
{
	if(log) delete log;
}



//-----------------------------------------------------------
// 函数名称:
//     encrypt
// 参数:
//    - string text	待加密明文
//    - string pwd_base64	对称密钥base64码
// 返回:
//     Result*
// 说明:
//     AES对称加密
//-----------------------------------------------------------
Result* CEncryptAES::encrypt(string text, string pwd_base64)
{

	HCRYPTPROV hCryptProv = NULL;
	HCRYPTKEY hKey = 0;
	HCRYPTHASH hHash = 0;
	int dwLength = 0;

	if(!CryptAcquireContext(&hCryptProv,
		NULL,
		this->CSP_NAME,//CSP_NAME
		PROV_RSA_AES,
		CRYPT_VERIFYCONTEXT))
	{
		DWORD dwLastErr = GetLastError();

		if(NTE_BAD_KEYSET == dwLastErr) 
		{
			Result* result = new Result("EncryptAES.cpp",54,"密钥库不存在,或者访问被拒绝!","{}");
			return result;
		}
		else{
			if(!CryptAcquireContext(&hCryptProv,
				NULL,
				this->CSP_NAME,
				PROV_RSA_AES,
				CRYPT_NEWKEYSET))
			{
				Map* map = new Map(1);
				map->put("errcode",dwLastErr);
				string errcode = map->toString();
				delete map;
				Result* result = new Result("EncryptAES.cpp",68,"密钥库已存在,创建密钥库失败!",errcode);
				return result;
			}
		}
	}


	HCRYPTPROV_Holder holder(hCryptProv);

	if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))
	{
		string errorcode = getErrorCode();
		Result* result = new Result("EncryptAES.cpp",87,"创建hash对象失败!",errorcode.length()==0?"{}":errorcode);
		if(hKey) CryptDestroyKey(hKey);
		if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
		return result;
	}

	//hash密钥字符串
	BYTE *pPwd = Base64::base64_decode(pwd_base64,dwLength);
	if(!CryptHashData(hHash, pPwd, dwLength, 0))
	{
		string errorcode = getErrorCode();
		Result* result = new Result("EncryptAES.cpp",103,"对密钥做hash运算失败!",errorcode.length()==0?"{}":errorcode);
		if(pPwd) delete []pPwd;
		if(hHash) CryptDestroyHash(hHash);
		if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
		return result;
	}

	// 基于hash的密钥获取会话密钥
	if(!CryptDeriveKey(hCryptProv, CALG_AES_128, hHash, CRYPT_EXPORTABLE, &hKey))
	{
		string errorcode = getErrorCode();
		Result* result = new Result("EncryptAES.cpp",111,"获取会话密钥失败!",errorcode.length()==0?"{}":errorcode);
		if(pPwd) delete []pPwd;
		if(hHash) CryptDestroyHash(hHash);
		if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
		return result;
	}

	int len = text.length();
	BYTE *pData ;
	pData = new BYTE[len*4];
	for(int i = 0; i < len; ++i)
	{
		pData[i] = (byte)text[i];
	}
	pData[len] = '\0';
	DWORD dwLen = len;

	if(!CryptEncrypt(hKey, NULL, true, 0, pData, &dwLen, len*4))
	{
		string errorcode = getErrorCode();
		Result* result = new Result("EncryptAES.cpp",130,"对称加密失败!",errorcode.length()==0?"{}":errorcode);
		if(pData) delete []pData;
		if(pPwd) delete []pPwd;
		if(hKey) CryptDestroyKey(hKey);
		if(hHash) CryptDestroyHash(hHash);
		if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
		return result;
	}

	pData[dwLen]='\0';
	string tobeDeBase = Base64::base64_encode(pData,dwLen);

	if(pData) delete []pData;
	if(pPwd) delete []pPwd;
	if(hKey) CryptDestroyKey(hKey);
	if(hHash) CryptDestroyHash(hHash);
	if(hCryptProv) CryptReleaseContext(hCryptProv, 0);

	Result* result = new Result(tobeDeBase);
	return result;
}



//-----------------------------------------------------------
// 函数名称:
//     decrypt
// 参数:
//    - string encrypted	待解密密文
//    - string pwd_base64	对称密钥base64码
// 返回:
//     Result*
// 说明:
//     AES对称解密
//-----------------------------------------------------------
Result* CEncryptAES::decrypt(string encrypted, string pwd_base64)
{
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTKEY hKey = 0;
	HCRYPTHASH hHash = 0;
	int dwLength = 0;
	BYTE *pData ;
	int len;
	pData =Base64::base64_decode(encrypted,len);

	if(!CryptAcquireContext(&hCryptProv,
		NULL,
		CSP_NAME,
		PROV_RSA_AES,
		CRYPT_VERIFYCONTEXT))
	{
		DWORD dwLastErr = GetLastError();

		if(NTE_BAD_KEYSET == dwLastErr) 
		{
			if(pData) delete []pData;
			Result* result = new Result("EncryptAES.cpp",146,"密钥库不存在,或者访问被拒绝!","{}");
			return result;
		}
		else{
			if(!CryptAcquireContext(&hCryptProv,
				NULL,
				this->CSP_NAME,
				PROV_RSA_AES,
				CRYPT_NEWKEYSET))
			{
				if(pData) delete []pData;
				Map* map = new Map(1);
				map->put("errcode",dwLastErr);
				string errcode = map->toString();
				delete map;
				Result* result = new Result("EncryptAES.cpp",160,"密钥库已存在,创建密钥库失败!",errcode);
				return result;
			}
		}
	}

	HCRYPTPROV_Holder holder(hCryptProv);

	if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))
	{
		string errorcode = getErrorCode();
		Result* result = new Result("EncryptAES.cpp",178,"创建hash对象失败!",errorcode.length()==0?"{}":errorcode);
		if(pData) delete []pData;
		if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
		return result;
	}
	BYTE *pPwd = Base64::base64_decode(pwd_base64,dwLength);
	if(!CryptHashData(hHash, pPwd, dwLength, 0))
	{
		string errorcode = getErrorCode();
		Result* result = new Result("EncryptAES.cpp",185,"HASH摘要失败!",errorcode.length()==0?"{}":errorcode);
		if(pData) delete []pData;
		if(pPwd) delete []pPwd;
		if(hHash) CryptDestroyHash(hHash);
		if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
		return result;
	}

	if(!CryptDeriveKey(hCryptProv, CALG_AES_128, hHash, CRYPT_EXPORTABLE, &hKey))
	{
		string errorcode = getErrorCode();
		Result* result = new Result("EncryptAES.cpp",192,"获取密钥失败!",errorcode.length()==0?"{}":errorcode);
		if(pData) delete []pData;
		if(pPwd) delete []pPwd;
		if(hHash) CryptDestroyHash(hHash);
		if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
		return result;
	}


	DWORD dwLen = len;


	if(!CryptDecrypt(hKey, NULL, true, 0, pData, &dwLen))
	{
		string errorcode = getErrorCode();
		Result* result = new Result("EncryptAES.cpp",203,"解密失败!",errorcode.length()==0?"{}":errorcode);
		if(pData) delete []pData;
		if(pPwd) delete []pPwd;
		if(hKey) CryptDestroyKey(hKey);
		if(hHash) CryptDestroyHash(hHash);
		if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
		return result;
	}

	char* pData_pchar = new char[dwLen + 1];

	for(int i = 0 ; i < dwLen; i++)
	{
		pData_pchar[i] = pData[i];
	}
	pData_pchar[dwLen] = '\0';

	string resultData = pData_pchar;

	if(pData) delete []pData;
	if(pPwd) delete []pPwd;
	if(hKey) CryptDestroyKey(hKey);
	if(hHash) CryptDestroyHash(hHash);
	if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
	Result* result = new Result(resultData);
	return result;
}
//-----------------------------------------------------------
// 函数名称:
//     generateSymmetricKey
// 参数:
//    - 无参数
// 返回:
//     Result*
// 说明:
//     生成会话密钥
//-----------------------------------------------------------
Result* CEncryptAES::generateSymmetricKey()
{
	HCRYPTPROV   hCryptProv;
	if(!CryptAcquireContext(&hCryptProv,
		NULL,
		CSP_NAME,
		PROV_RSA_AES,
		CRYPT_VERIFYCONTEXT))
	{
		DWORD dwLastErr = GetLastError();

		if(NTE_BAD_KEYSET == dwLastErr) 
		{
			Result* result = new Result("EncryptAES.cpp",248,"密钥库不存在,或者访问被拒绝!","{}");
			return result;
		}
		else{
			if(!CryptAcquireContext(&hCryptProv,
				NULL,
				this->CSP_NAME,
				PROV_RSA_AES,
				CRYPT_NEWKEYSET))
			{
				Map* map = new Map(1);
				map->put("errcode",dwLastErr);
				string errcode = map->toString();
				delete map;
				Result* result = new Result("EncryptAES.cpp",262,"密钥库已存在,创建密钥库失败!",errcode);
				return result;
			}
		}
	}
	BYTE  pbData[9];
	if(!CryptGenRandom(
		hCryptProv, 
		8, 
		pbData)) 
	{
		string errorcode = getErrorCode();
		Result* result = new Result("EncryptAES.cpp",278,"生成随机数失败!",errorcode.length()==0?"{}":errorcode);
		return result;
	}
	string key_base64 = Base64::base64_encode(pbData,9);

	if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
	return new Result(key_base64);
}






------------------------------下面为刚接触的版本,上面为修改后的版本--------------------------

代码有待修改

3DES对称加密与解密

#include "Base.h"
#include <comdef.h>
#include "generic.h"
#include <iostream>
using namespace std;
//3DES对称加密
STDMETHODIMP CEncrypt3DES::Encrypt(BSTR text, BSTR pwd, BSTR* encrypted)
{
	// TODO: Add your implementation code here
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTKEY hKey = 0;
	HCRYPTHASH hHash = 0;
	DWORD dwLength = 0;

	// Create a keyset(aka container), if the keyset already exists,
	// delete it and re-create it.

	if(!CryptAcquireContext(&hCryptProv,
				NULL,
				TEST_CSP_NAME,
				PROV_RSA_FULL,
				0))
	{
		DWORD dwLastErr = GetLastError();

		if(0x8009000F == dwLastErr) //  Object already exists.
		{
			 CComBSTR bstr("error:密钥库已存在");
		*encrypted = bstr;
			return S_FALSE;
		}
		else{
			if(!CryptAcquireContext(&hCryptProv,
						NULL,
						TEST_CSP_NAME,
						PROV_RSA_FULL,
						CRYPT_NEWKEYSET))
			{
				 CComBSTR bstr("error:创建新密钥库");
		         *encrypted = bstr;
				return S_FALSE;
			}
		}
	}
	else
	{
	}

	// Hold the handle and release when this function return.
	HCRYPTPROV_Holder holder(hCryptProv);

	// Create a hash object.
	if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))
	{
		 CComBSTR bstr("error:创建hash对象失败");
		*encrypted = bstr;
				return S_FALSE;
	}
	else
	{
	}

	// Hash the password string.
	dwLength = SysStringLen(pwd);
	BYTE *pPwd ;
	pPwd = new BYTE[dwLength];
      for(int i = 0; i < dwLength; ++i)
      {
            pPwd[i] = (byte)pwd[i];
      }
    pPwd[dwLength] = '\0';
	if(!CryptHashData(hHash, pPwd, dwLength, 0))
	{
		 CComBSTR bstr("error:散列失败");
		*encrypted = bstr;
				return S_FALSE;
	}
	else
	{
	}

	// Create a block cipher session key based on the hash of the password.
	if(!CryptDeriveKey(hCryptProv, CALG_3DES, hHash, CRYPT_EXPORTABLE, &hKey))
	{
		 CComBSTR bstr("error:获取密钥失败");
		*encrypted = bstr;
				return S_FALSE;
	}
	else
	{
	}
	//Encrypt Data with RC2 key:
	int len = SysStringLen(text);
	BYTE *pData ;
	pData = new BYTE[len*2];
      for(int i = 0; i < len; ++i)
      {
            pData[i] = (byte)text[i];
      }
    pData[len] = '\0';
	DWORD dwLen = lstrlen((LPCTSTR) pData);//60;

	//encrypt:
	if(!CryptEncrypt(hKey, NO_HASH, LAST_DATA, 0, pData, &dwLen, len*2))
	{
		int a = GetLastError();
		 CComBSTR bstr("error:加密失败");
		*encrypted = bstr;
		return S_FALSE;
	}
	else
	{
	}
	pData[dwLen]='\0';
	//cout<<base64_encode(pData,dwLen).c_str();
	int len0 = dwLen;
	string tobeDeBase = base64_encode(pData,dwLen);
	int len1 = tobeDeBase.length();
	string result = base64_decode(tobeDeBase);
	int len2 = result.length();
	CComBSTR bstr(base64_encode(pData,dwLen).c_str());
	
	//if(pData) free(pData);
//		if(pPwd) free(pPwd);
	if(hKey) CryptDestroyKey(hKey);
	if(hHash) CryptDestroyHash(hHash);
	if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
	*encrypted = bstr;
	return S_OK;
}



//3DES对称解密
STDMETHODIMP CEncrypt3DES::Decrypt(BSTR encrypted, BSTR pwd, BSTR* text)
{
	// TODO: Add your implementation code here
// TODO: Add your implementation code here
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTKEY hKey = 0;
	HCRYPTHASH hHash = 0;
	DWORD dwLength = 0;
	string temp = _bstr_t (encrypted);
	int len1 = temp.size();
	string toBeDec =base64_decode(temp);
	int len2 = toBeDec.length();
	// Create a keyset(aka container), if the keyset already exists,
	// delete it and re-create it.

	if(!CryptAcquireContext(&hCryptProv,
				NULL,
				TEST_CSP_NAME,
				PROV_RSA_FULL,
				0))
	{
		DWORD dwLastErr = GetLastError();

		if(0x8009000F == dwLastErr) //  Object already exists.
		{
			 CComBSTR bstr("error:密钥库已存在");
		*text = bstr;
			return S_FALSE;
		}
		else{
			if(!CryptAcquireContext(&hCryptProv,
						NULL,
						TEST_CSP_NAME,
						PROV_RSA_FULL,
						CRYPT_NEWKEYSET))
			{
				 CComBSTR bstr("error:创建新密钥库");
		         *text = bstr;
				return S_FALSE;
			}
		}
	}
	else
	{
	}

	// Hold the handle and release when this function return.
	HCRYPTPROV_Holder holder(hCryptProv);

	// Create a hash object.
	if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))
	{
		 CComBSTR bstr("error:创建hash对象失败");
		*text = bstr;
				return S_FALSE;
	}
	else
	{
	}

	// Hash the password string.
	dwLength = SysStringLen(pwd);
	BYTE *pPwd ;
	pPwd = new BYTE[dwLength];
      for(int i = 0; i < dwLength; ++i)
      {
            pPwd[i] = (byte)pwd[i];
      }
    pPwd[dwLength] = '\0';
	if(!CryptHashData(hHash, pPwd, dwLength, 0))
	{
		 CComBSTR bstr("error:散列失败");
		*text = bstr;
				return S_FALSE;
	}
	else
	{
	}

	// Create a block cipher session key based on the hash of the password.
	if(!CryptDeriveKey(hCryptProv, CALG_3DES, hHash, CRYPT_EXPORTABLE, &hKey))
	{
		int i = GetLastError();
		 CComBSTR bstr("error:获取密钥失败:"+i);
		*text = bstr;
				return S_FALSE;
	}
	else
	{
	}
	//Encrypt Data with RC2 key:
	int len = toBeDec.size();
	 BYTE *pData ;
	 pData = new BYTE[len] ;
      for(int i = 0; i < len; ++i)
      {
            pData[i] = (byte)toBeDec[i];
      }
    pData[len] = '\0';
	DWORD dwLen = len;//60;

	//encrypt:
	if(!CryptDecrypt(hKey, NO_HASH, LAST_DATA, 0, pData, &dwLen))
	{
		int err = GetLastError();
		 CComBSTR bstr("error:解密失败:"+err);
		*text = bstr;
		return S_FALSE;
	}
	else
	{
	}
	pData[dwLen]='\0';
	char* resultData = (char*)pData;
	CComBSTR plainText(resultData);
	*text = plainText;
	//if(resultData) free(resultData);
	//if(pData) free(pData);
	//if(pPwd) free(pPwd);
	if(hKey) CryptDestroyKey(hKey);
	if(hHash) CryptDestroyHash(hHash);
	if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
	return S_OK;
}

抱歉!评论已关闭.