EF AES Library 的封装类
发布日期:2021-06-30 22:06:09
浏览次数:2
分类:技术文章
本文共 12622 字,大约阅读时间需要 42 分钟。
昨天要完成一个参数文件加密存储的子任务, 在CodeProject上找到一个 <<EF AES Library>>, 很易用.
但是原始Demo中, 那个文件操作,有点问题, 会导致报错. 需要再处理一下.
完成任务之后,今天又琢磨了一下,在<<EF AES Library>>基础上, 封装了一个更易用的文件AES加解密类.
如果要完成类似任务,只需要从 CDtoAesOptBase 继承一个子类, 实现3个虚函数就搞定了.
工程下载点:
编译环境 : vs2010 vc++ + console
测试程序:
// srcAesOpt.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "aes_opt/dto_aes_opt.h"#include "aes_opt/AesKeyParam_128Bit.h"void fnTestAes(int iTaskSn);int _tmain(int argc, _TCHAR* argv[]){ int iTaskSn = 0; int iDoCnt = 3; do { fnTestAes(iTaskSn++); } while (--iDoCnt > 0); _tprintf(L"END, press any key to quit\r\n"); getwchar(); return 0;}void fnTestAes(int iTaskSn){ BOOL bTmp = FALSE; CDtoAesOpt AesOpt; ///< 定义自己的CDtoAesOpt即可, 工作量很小. CAesKeyParam128Bit AesKeyParam; _tprintf(L"[%d]==>\r\n", iTaskSn); if (AesOpt.LoadFromDisk(&AesKeyParam)) { bTmp = AesOpt.geter_ShowAlertOnce(); _tprintf(L"load ok, AesOpt.geter_ShowAlertOnce() = %d\r\n", bTmp); } else { _tprintf(L"load err\r\n"); } AesOpt.seter_ShowAlertOnce(!bTmp); if (AesOpt.SaveToDisk(&AesKeyParam)) { _tprintf(L"save ok\r\n"); } else { _tprintf(L"save err\r\n"); } if (AesOpt.LoadFromDisk(&AesKeyParam)) { bTmp = AesOpt.geter_ShowAlertOnce(); _tprintf(L"load ok, AesOpt.geter_ShowAlertOnce() = %d\r\n", bTmp); } else { _tprintf(L"load err\r\n"); }}运行结果:
[0]==>load ok, AesOpt.geter_ShowAlertOnce() = 0save okload ok, AesOpt.geter_ShowAlertOnce() = 1[1]==>load ok, AesOpt.geter_ShowAlertOnce() = 1save okload ok, AesOpt.geter_ShowAlertOnce() = 0[2]==>load ok, AesOpt.geter_ShowAlertOnce() = 0save okload ok, AesOpt.geter_ShowAlertOnce() = 1END, press any key to quit封装类的基类
/// @file dto_aes_opt_base.h/// @brief 数据传送类, 文件AES读写类的基类#ifndef __DTO_AES_OPT_BASE_H__#define __DTO_AES_OPT_BASE_H__#include "stdafx.h"#include "aes_opt/IAesKeyParam.h"class CDtoAesOptBase{public: enum param { param_SizeMinBlock = 4096, param_SizeKey = 16, };public: CDtoAesOptBase(); virtual ~CDtoAesOptBase(void); // 成员函数public: BOOL LoadFromDisk(IAesKeyParam* pOwner); BOOL SaveToDisk(IAesKeyParam* pOwner);protected: virtual std::wstring GetLocalFilePathName() = 0; virtual BOOL Buffer2Member() = 0; virtual void Member2Buffer() = 0; void setBuffer(unsigned char* pBuf) {m_pBuffer = pBuf;} unsigned char* getBuffer() {return m_pBuffer;} void setBufferSize(size_t nLen) {m_nLenBuffer = nLen;} size_t getBufferSize() {return m_nLenBuffer;} void SetVersion(LONGLONG llVer) {m_llVersion = llVer;} LONGLONG GetVersion() {return m_llVersion;} void Lock() {m_Locker.enter(L"CDtoAesOptBase");} void UnLock() {m_Locker.leave();}private: void AesKeyInit(); // 成员变量private: ns_base::CCriticalSection m_Locker; unsigned char* m_pBuffer; size_t m_nLenBuffer; LONGLONG m_llVersion; unsigned char m_cAesKey[CDtoAesOptBase::param_SizeKey]; unsigned char m_cAesVector[CDtoAesOptBase::param_SizeKey];};#endif // #ifndef __DTO_AES_OPT_BASE_H__
/// @file aes_opt\dto_aes_opt_base.cpp#include "StdAfx.h"#include干活用的子类,方便调用者, 构造起来很简单.#include "dto_aes_opt_base.h"#include "AES/EfAes.H"#include "stringHelper/StringHelper.h"#include "FileHelper/FileHelper.h"#include "UtilityHelper/constDefine.h"#include "UtilityHelper/UtilityHelper.h"CDtoAesOptBase::CDtoAesOptBase() : m_llVersion(201507041540){ AesKeyInit(); m_pBuffer = NULL; m_nLenBuffer = 0;}CDtoAesOptBase::~CDtoAesOptBase(void){}void CDtoAesOptBase::AesKeyInit(){ int iIndex = 0; unsigned char key[CDtoAesOptBase::param_SizeKey]={ 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88, 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88 }; unsigned char vector[CDtoAesOptBase::param_SizeKey]={ 0x1f,0x32,0x43,0x51,0x56,0x98,0xaf,0xed, 0xab,0xc8,0x21,0x45,0x63,0x72,0xac,0xfc }; for (iIndex = 0; iIndex < CDtoAesOptBase::param_SizeKey; iIndex++) { m_cAesKey[iIndex] = key[iIndex]; m_cAesVector[iIndex] = vector[iIndex]; }}BOOL CDtoAesOptBase::LoadFromDisk(IAesKeyParam* pOwner){ HANDLE hfile = NULL; DWORD dwRdBk= 0; unsigned char* pDataBuf = NULL; BOOL bLoadDataOk = FALSE; size_t nPosDataBuf = 0; std::string strAesKeyA = ""; int iMyKeyLen = 0; int iIndex = 0; int rdsz = 0; AesCtx context; unsigned char buff[param_SizeMinBlock]; do { if (NULL == pOwner) break; pDataBuf = getBuffer(); if (NULL == pDataBuf) break; strAesKeyA = ns_base::W2Aex(pOwner->GetAesKey().c_str()).c_str(); iMyKeyLen = pOwner->GetAesKeyLen(); if (iMyKeyLen > CDtoAesOptBase::param_SizeKey) iMyKeyLen = CDtoAesOptBase::param_SizeKey; AesKeyInit(); for (iIndex = 0; iIndex < iMyKeyLen; iIndex++) { m_cAesKey[iIndex] = strAesKeyA[iIndex]; } AesSetKey(&context, AES_KEY_128BIT, BLOCKMODE_CRT, m_cAesKey, m_cAesVector); do { if (!ns_base::OpenFileReadBinary(GetLocalFilePathName().c_str(), hfile)) break; while (1) { rdsz = CDtoAesOptBase::param_SizeMinBlock; if (!ns_base::ReadFileBinary(hfile, buff, rdsz, dwRdBk)) break; // before last block , the block size // should always be the multiply of 16 // the last block should be handled // if the size is not a multiply of 16 AesDecryptCRT(&context , buff, buff, rdsz); rdsz = AesRoundSize( rdsz, CDtoAesOptBase::param_SizeKey); if ((nPosDataBuf + dwRdBk) > getBufferSize()) { break; } memcpy((char*)pDataBuf + nPosDataBuf, buff, dwRdBk); nPosDataBuf += dwRdBk; } ns_base::CloseFileHandle(hfile); } while (0); bLoadDataOk = (nPosDataBuf == getBufferSize()); } while (0); if (bLoadDataOk) { bLoadDataOk = Buffer2Member(); ///< 如果文件版本不对,算作载入失败 } return bLoadDataOk;}BOOL CDtoAesOptBase::SaveToDisk(IAesKeyParam* pOwner){ HANDLE hfile = NULL; BOOL bRc = FALSE; unsigned char* pDataBuf = NULL; size_t nPosDataBuf = 0; size_t nLeftDataBuf = 0; std::string strAesKeyA = ""; int iMyKeyLen = 0; int iIndex = 0; int rdsz = 0; DWORD dwWrBk = 0; AesCtx context; unsigned char buff[CDtoAesOptBase::param_SizeMinBlock]; do { if (NULL == pOwner) break; pDataBuf = getBuffer(); if (NULL == pDataBuf) break; Member2Buffer(); strAesKeyA = ns_base::W2Aex(pOwner->GetAesKey().c_str()).c_str(); iMyKeyLen = pOwner->GetAesKeyLen(); if (iMyKeyLen > CDtoAesOptBase::param_SizeKey) iMyKeyLen = CDtoAesOptBase::param_SizeKey; AesKeyInit(); for (iIndex = 0; iIndex < iMyKeyLen; iIndex++) { m_cAesKey[iIndex] = strAesKeyA[iIndex]; } AesSetKey(&context, AES_KEY_128BIT, BLOCKMODE_CRT, m_cAesKey, m_cAesVector); if (!ns_base::OpenFileWriteBinary(GetLocalFilePathName().c_str(), hfile)) break; nLeftDataBuf = getBufferSize(); _ASSERT(0 == (nLeftDataBuf % CDtoAesOptBase::param_SizeMinBlock)); nPosDataBuf = 0; while (nLeftDataBuf > 0) { rdsz = CDtoAesOptBase::param_SizeMinBlock; memcpy(buff, (char*)pDataBuf + nPosDataBuf, rdsz); // before last block , the block size // should always be the multiply of 16 // the last block should be handled // if the size is not a multiply of 16 AesEncryptCRT(&context , buff, buff, rdsz ); rdsz = AesRoundSize( rdsz, CDtoAesOptBase::param_SizeKey); ns_base::WriteFileBinary(hfile, buff, rdsz, dwWrBk); nPosDataBuf += rdsz; nLeftDataBuf -= rdsz; } ns_base::CloseFileHandle(hfile); bRc = TRUE; } while (0); ns_base::SetFilePermissionToEveryOne_Real(GetLocalFilePathName().c_str()); return bRc;}
/// @file dto_aes_opt.h/// @brief 数据传送类, 记录参数文件加密相关的数据#ifndef __DTO_AES_OPT_H__#define __DTO_AES_OPT_H__#include "stdafx.h"#include "dto_aes_opt_base.h"#include "AesKeyParam_128Bit.h"class CDtoAesOpt : public CDtoAesOptBase{public: typedef struct _tag_data_buf { union { char cArrReserve[CDtoAesOptBase::param_SizeMinBlock * 4]; struct { LONGLONG llVer; ///< 必须设置版本号, 防止读入的数据不正确 BOOL bUserChoiceNotAlert; ///< 用户选择不弹出提示框 BOOL bShowAlertOnce; ///< 开机后, 已经显示过一次提示 }; }; _tag_data_buf() { ZeroMemory(cArrReserve, sizeof(cArrReserve)); llVer = 0; bUserChoiceNotAlert = FALSE; bShowAlertOnce = FALSE; } }TAG_DATA_BUF;public: CDtoAesOpt(); virtual ~CDtoAesOpt(void); // 成员函数public: /// 必须实现的纯虚函数 virtual std::wstring GetLocalFilePathName(); virtual BOOL Buffer2Member(); virtual void Member2Buffer(); /// 自己的成员变量存取函数 BOOL geter_UserChoiceNotAlert() {return m_bUserChoiceNotAlert;} void seter_UserChoiceNotAlert(BOOL bIn) {m_bUserChoiceNotAlert = bIn;} BOOL geter_ShowAlertOnce() {return m_bShowAlertOnce;} void seter_ShowAlertOnce(BOOL bIn) {m_bShowAlertOnce = bIn;}private: /// 初始化函数 void DataInit(); void DataUnInit(); // 成员变量private: BOOL m_bUserChoiceNotAlert; ///< 用户选择不弹出提示框 BOOL m_bShowAlertOnce; ///< 开机后, 已经显示过一次提示};#endif // #ifndef __DTO_AES_OPT_H__
/// @file dto_aes_opt.cpp#include "StdAfx.h"#includeAesKey参数接口#include "dto_aes_opt.h"#include "AES/EfAes.H"#include "stringHelper/StringHelper.h"#include "FileHelper/FileHelper.h"#include "UtilityHelper/constDefine.h"#include "UtilityHelper/UtilityHelper.h"CDtoAesOpt::CDtoAesOpt(){ SetVersion(201507041552); ///< 必须设置自己的版本, 防止文件序列化后,读到的文件格式不符合预期 DataInit();}CDtoAesOpt::~CDtoAesOpt(void){ DataUnInit();}void CDtoAesOpt::DataInit(){ setBuffer((unsigned char*)(new TAG_DATA_BUF)); setBufferSize(sizeof(TAG_DATA_BUF)); if (NULL != getBuffer()) ZeroMemory(getBuffer(), getBufferSize()); m_bShowAlertOnce = FALSE; m_bUserChoiceNotAlert = FALSE;}void CDtoAesOpt::DataUnInit(){ unsigned char* pBuffer = getBuffer(); SAFE_DELETE(pBuffer); setBuffer(pBuffer);}BOOL CDtoAesOpt::Buffer2Member(){ BOOL bRc = FALSE; do { if (NULL == getBuffer()) break; m_bUserChoiceNotAlert = ((TAG_DATA_BUF*)getBuffer())->bUserChoiceNotAlert; m_bShowAlertOnce = ((TAG_DATA_BUF*)getBuffer())->bShowAlertOnce; bRc = (GetVersion() == ((TAG_DATA_BUF*)getBuffer())->llVer); } while (0); return bRc;}void CDtoAesOpt::Member2Buffer(){ do { if (NULL == getBuffer()) break; ((TAG_DATA_BUF*)getBuffer())->llVer = GetVersion(); ((TAG_DATA_BUF*)getBuffer())->bUserChoiceNotAlert = m_bUserChoiceNotAlert; ((TAG_DATA_BUF*)getBuffer())->bShowAlertOnce = m_bShowAlertOnce; } while (0);}std::wstring CDtoAesOpt::GetLocalFilePathName(){ std::wstring strCfgFilePathName = L""; Lock(); /// 根据实际情况来, 这里假设文件为 APPDATA\test.dat ns_base::GetAppDataDir(strCfgFilePathName); strCfgFilePathName += L"test.dat"; UnLock(); return strCfgFilePathName;}
/// @file aes_opt\IAesKeyParam.h#include "stdafx.h"#include子类用的AesKey参数类, 从接口 IAesKeyParam继承#ifndef __AES_OPT_IAESOPTOWNER_H__#define __AES_OPT_IAESOPTOWNER_H__interface IAesKeyParam{ virtual std::wstring GetAesKey() = 0; virtual size_t GetAesKeyLen() = 0;};#endif
/// @file aes_opt\AesKeyParam_128Bit.h#ifndef __AES_OPT_AESOPTONWER_128BIT_H__#define __AES_OPT_AESOPTONWER_128BIT_H__#include "IAesKeyParam.h"class CAesKeyParam128Bit : public IAesKeyParam{public: CAesKeyParam128Bit(void); virtual ~CAesKeyParam128Bit(void); virtual std::wstring GetAesKey(); virtual size_t GetAesKeyLen();private: const std::wstring m_strAesKey;};#endif // #ifndef __AES_OPT_AESOPTONWER_128BIT_H__
#include "StdAfx.h"#include "AesKeyParam_128Bit.h"CAesKeyParam128Bit::CAesKeyParam128Bit(void) : m_strAesKey(L"123456"){}CAesKeyParam128Bit::~CAesKeyParam128Bit(void){}std::wstring CAesKeyParam128Bit::GetAesKey(){ /// 实际工程中, 口令是从别的途径来的 /// 口令使用时, 会转成char*, 128Bit是8个字节 /// 超过8个字节的口令内容用不到了 return m_strAesKey;}size_t CAesKeyParam128Bit::GetAesKeyLen(){ return _tcslen(GetAesKey().c_str());}
转载地址:https://lostspeed.blog.csdn.net/article/details/46756405 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2024年04月14日 14时25分03秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
YbtOJ——字符串处理【例题1】数字反转
2019-04-30
YbtOJ——字符串处理【例题2】移位包含
2019-04-30
转trt步骤记录
2019-05-01
MatConvNet安装
2019-05-01
依赖错误
2019-05-01
ROS安装与卸载
2019-05-01
openrave安装
2019-05-01
安装openrave 0.9的各种依赖包
2019-05-01
trajopt代码使用
2019-05-01
kpm代码使用细节
2019-05-01
kpm代码使用步骤
2019-05-01
.jar文件格式
2019-05-01
用原生java实现Spring以及SpringMVC(一)
2019-05-01
用原生java实现Spring以及SpringMVC(二)
2019-05-01
关于表单屏蔽浏览器自动记住密码/自动明文提示的解决方案
2019-05-01
JAVA中线程的各种状态
2019-05-01
WEB前端语音对讲实现方案以及示例
2019-05-01
Eureka和Consul的区别
2019-05-01
Kafka如何做到高可用及保证写入数据不丢失
2019-05-01