您的位置:首页 > 其它

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

2016-04-04 17:27 603 查看
注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出.

[cpp] view
plain copy

print?

/*

*

*

* 文件名称: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对称加密与解密

[cpp] view
plain copy

print?

#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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: