注:下面的代码中用了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; }