MD5 计算 (下一代加密辅助类, Win32, C++)

CCNGHelper.h

#pragma once
#include <string>
#include <tchar.h>
#include <windows.h>
#include <bcrypt.h>#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif// 下一代加密辅助类
// 客户端: Windows Vista 及以上系统可用
// 服务器: Windows Server 2008 及以上系统可用
class CCNGHelper
{
public:CCNGHelper();~CCNGHelper();//// @brief: 初始化// @param: strAlgorithm     哈希算法名字符串, 可选类型如下://                          常见可选 "MD5", "SHA1", "SHA256", "SHA384", "SHA512"// //                          全部支持可选如下://                          "RSA", "RSA_SIGN", "DH", "DSA", "RC2", "RC4", "AES", "DES", "DESX", "3DES", "3DES_112", //                          "MD2", "MD4", "MD5", "SHA1", "SHA256", "SHA384", "SHA512",//                          "AES-GMAC", "AES-CMAC", "ECDSA_P256", "ECDSA_P384", "ECDSA_P521", "ECDH_P256", "ECDH_P384", "ECDH_P521", //                          "RNG", "FIPS186DSARNG", "DUAECRNG"//                          WINDOWS 8 及以上: "SP800_108_CTR_HMAC", "SP800_56A_CONCAT", "PBKDF2", "CAPI_KDF", "TLS1_1_KDF", "TLS1_2_KDF"//                          Windows 10 及以上: "ECDSA", "ECDH", "XTS-AES"//                          Windows 10 1803: "HKDF"//                          "CHACHA20_POLY1305"// // @ret: bool               操作是否成功bool Initialize(const _tstring& strAlgorithm = _T("MD5"));//// @brief: 反初始化// @ret: 无void Uninitialize();//// @brief: 重置// @ret: 无void Reset();//// @brief: 计算哈希值// @param: pData            数据缓冲// @param: ulSize           数据长度// @ret: bool               操作是否成功bool HashData(const void* pData, unsigned long long ulSize);//// @brief: 获取累积的哈希值结果// @param: bUpper           是否大写// @ret: _tstring           哈希值字符串_tstring FinishHash(bool bUpper = true);//// @brief: 获取文件的哈希值结果// @param: strPath          文件路径// @param: bUpper           是否大写// @ret: _tstring           哈希值结果字符串_tstring GetFileHash(const _tstring& strPath, bool bUpper = true);//// @brief: 获取数据的哈希值结果// @param: pData            数据指针// @param: ullSize          数据长度// @param: bUpper           是否大写// @ret: _tstring           哈希值结果字符串_tstring GetDataHash(const void* pData,unsigned long long ullSize,bool bUpper = true);private://// @brief: 计算哈希// @param: pData            数据指针// @param: ulSize           数据长度// @ret: 无bool _HashData(const void* pData, unsigned long ulSize);//// @brief: 字节内容转字符串// @param: pData            数据指针// @param: nSize            数据长度// @param: bUpper           是否大写// @ret: _tstring           转换后的字符串_tstring _BytesToString(const void* pData, size_t nSize, bool bUpper = true);//// @brief: 字符串转大小// @param: str              字符串// @ret: _tstring           转换后的字符串_tstring _ToUpper(const _tstring& str);//// @brief: 多字符字符串转宽字符串// @param: CodePage         代码页// @param: str              字符串// @ret: std::wstring       转换后的宽字符串std::wstring _MultiStrToWStr(UINT CodePage, const std::string& str);//// @brief: 字符串转宽字符串// @param: str              字符串// @ret: std::wstring       转换后的宽字符串std::wstring _TStrToWStr(const _tstring& str);private:BCRYPT_ALG_HANDLE       m_hAlg = NULL;              // 算法提供程序句柄BCRYPT_HASH_HANDLE      m_hHash = NULL;             // 哈希对象句柄PBYTE                   m_pbHashObject = NULL;      // 哈希对象内存PBYTE                   m_pbHash = NULL;            // 哈希值缓冲DWORD                   m_cbHash = 0;               // 哈希值缓冲大小_tstring                m_strAlgorithm;             // 算法名std::string             m_dataBuf;                  // 数据缓冲(用于文件读取)
};

CCNGHelper.cpp

#include "CCNGHelper.h"
#include <Wincrypt.h>#pragma comment(lib,"Bcrypt.lib")#define NT_SUCCESS(Status)          (((NTSTATUS)(Status)) >= 0)
#define STATUS_UNSUCCESSFUL         ((NTSTATUS)0xC0000001L)
#define FILE_HASH_BLOCK_SIZE        (1024 * 1024 * 4)CCNGHelper::CCNGHelper():m_hAlg(NULL),m_hHash(NULL),m_pbHashObject(NULL),m_pbHash(NULL),m_cbHash(0)
{}CCNGHelper::~CCNGHelper()
{Uninitialize();
}bool CCNGHelper::Initialize(const _tstring& strAlgorithm/* = _T("MD5")*/
)
{bool bSuccess = false;NTSTATUS status = STATUS_UNSUCCESSFUL;DWORD cbData = 0;DWORD cbHashObject = 0;_tstring strAlgorithmName = _ToUpper(strAlgorithm);if (m_strAlgorithm == strAlgorithmName){return true;}Uninitialize();do{// 打开一个算法句柄// https://learn.microsoft.com/zh-cn/windows/win32/api/bcrypt/nf-bcrypt-bcryptopenalgorithmproviderstatus = BCryptOpenAlgorithmProvider(&m_hAlg, //指向接收 CNG 提供程序句柄 的 BCRYPT_ALG_HANDLE 变量的指针strAlgorithmName.c_str(), //指向以 null 结尾的 Unicode 字符串的指针,该字符串标识请求的加密算法NULL, //指向以 null 结尾的 Unicode 字符串的指针,该字符串标识要加载的特定提供程序BCRYPT_HASH_REUSABLE_FLAG//修改函数行为的标志);if (!NT_SUCCESS(status)){break;}// 检索提供程序的子对象的大小(以字节为单位)// https://learn.microsoft.com/zh-cn/windows/win32/api/bcrypt/nf-bcrypt-bcryptgetpropertystatus = BCryptGetProperty(m_hAlg, //表示要获取其属性值的 CNG 对象的句柄BCRYPT_OBJECT_LENGTH, //指向以 null 结尾的 Unicode 字符串的指针,该字符串包含要检索的属性的名称(PBYTE)&cbHashObject, //接收属性值的缓冲区的地址sizeof(DWORD), //pbOutput 缓冲区的大小(以字节为单位)&cbData, //指向 ULONG 变量的指针,该变量接收复制到 pbOutput 缓冲区的字节数0 //一组标志,用于修改此函数的行为。 未为此函数定义任何标志);if (!NT_SUCCESS(status)){break;}// 在堆上分配哈希对象m_pbHashObject = (PBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbHashObject);if (NULL == m_pbHashObject){break;}// 检索哈希提供程序的哈希值的大小(以字节为单位)// https://learn.microsoft.com/zh-cn/windows/win32/api/bcrypt/nf-bcrypt-bcryptgetpropertystatus = BCryptGetProperty(m_hAlg, //表示要获取其属性值的 CNG 对象的句柄BCRYPT_HASH_LENGTH, //指向以 null 结尾的 Unicode 字符串的指针,该字符串包含要检索的属性的名称(PBYTE)&m_cbHash, //接收属性值的缓冲区的地址sizeof(DWORD), //pbOutput 缓冲区的大小(以字节为单位)&cbData, //指向 ULONG 变量的指针,该变量接收复制到 pbOutput 缓冲区的字节数0 //一组标志,用于修改此函数的行为。 未为此函数定义任何标志);if (!NT_SUCCESS(status)){break;}// 在堆上分配哈希缓冲区m_pbHash = (PBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, m_cbHash);if (NULL == m_pbHash){break;}// 创建哈希对象// https://learn.microsoft.com/zh-cn/windows/win32/api/bcrypt/nf-bcrypt-bcryptcreatehashstatus = ::BCryptCreateHash(m_hAlg, //创建提供程序时指定的算法必须支持哈希接口&m_hHash, //哈希或 MAC 对象的句柄m_pbHashObject, //接收哈希或 MAC 对象的缓冲区的指针cbHashObject, //pbHashObject 缓冲区的大小(以字节为单位)NULL, //指向缓冲区的指针0, //pbSecret 缓冲区的大小(以字节为单位)BCRYPT_HASH_REUSABLE_FLAG //修改函数行为的标志);if (!NT_SUCCESS(status)){break;}bSuccess = true;} while (false);if (bSuccess){m_strAlgorithm = strAlgorithmName;}else{Uninitialize();}return bSuccess;
}void CCNGHelper::Uninitialize()
{if (m_hAlg){::BCryptCloseAlgorithmProvider(m_hAlg, 0);m_hAlg = NULL;}if (m_hHash){::BCryptDestroyHash(m_hHash);m_hHash = NULL;}if (m_pbHashObject){::HeapFree(GetProcessHeap(), 0, m_pbHashObject);m_pbHashObject = NULL;}if (m_pbHash){::HeapFree(GetProcessHeap(), 0, m_pbHash);m_pbHash = NULL;}m_strAlgorithm.clear();
}void CCNGHelper::Reset()
{if (!m_strAlgorithm.empty()){// 检索从先前调用 BCryptHashData 累积的数据的哈希值(void)::BCryptFinishHash(m_hHash, //用于计算哈希或 MAC 的哈希或 MAC 对象的句柄m_pbHash, //指向接收哈希或 MAC 值的缓冲区的指针m_cbHash, //pbOutput 缓冲区的大小(以字节为单位)0 //一组标志,用于修改此函数的行为。 当前未定义任何标志,因此此参数应为零);}
}bool CCNGHelper::HashData(const void* lpData, unsigned long long ullSize
)
{const char* pDataBegin = (const char*)lpData;const unsigned long ulMaxBlockSize = UINT32_MAX;bool bSuccess = false;if (m_strAlgorithm.empty()){return false;}// 小于32位最大值则直接计算哈希值if (ullSize <= ulMaxBlockSize){return _HashData(pDataBegin, (unsigned long)ullSize);}// 分段计算哈希值while(ullSize > 0){unsigned long ulReadSize = (ullSize > ulMaxBlockSize) ? ulMaxBlockSize : (unsigned long)ullSize;if (!_HashData(pDataBegin, ulReadSize)){break;}pDataBegin += ulReadSize;ullSize -= ulReadSize;}return bSuccess;
}_tstring CCNGHelper::FinishHash(bool bUpper/* = true*/
)
{_tstring strResult;if (m_strAlgorithm.empty()){return strResult;}// 检索从先前调用 BCryptHashData 累积的数据的哈希值NTSTATUS status = ::BCryptFinishHash(m_hHash, //用于计算哈希或 MAC 的哈希或 MAC 对象的句柄m_pbHash, //指向接收哈希或 MAC 值的缓冲区的指针m_cbHash, //pbOutput 缓冲区的大小(以字节为单位)0 //一组标志,用于修改此函数的行为。 当前未定义任何标志,因此此参数应为零);if (NT_SUCCESS(status)){strResult = _BytesToString(m_pbHash, m_cbHash, bUpper);}return strResult;
}_tstring CCNGHelper::GetFileHash(const _tstring& strPath, bool bUpper/* = true*/
)
{HANDLE hFile = INVALID_HANDLE_VALUE;DWORD dwBlockSize = FILE_HASH_BLOCK_SIZE;DWORD dwBytesRead = 0;if (m_strAlgorithm.empty()){return _tstring(_T(""));}do{// 打开文件// https://learn.microsoft.com/zh-cn/windows/win32/api/fileapi/nf-fileapi-createfilewhFile = CreateFile(strPath.c_str(),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);if (INVALID_HANDLE_VALUE == hFile){break;}if (m_dataBuf.empty()){m_dataBuf.resize(dwBlockSize);}// 读取文件数据// https://learn.microsoft.com/zh-cn/windows/win32/api/fileapi/nf-fileapi-readfilewhile (::ReadFile(hFile, &m_dataBuf[0], dwBlockSize, &dwBytesRead, NULL)){if (0 == dwBytesRead){break;}if (!_HashData(&m_dataBuf[0], dwBytesRead)){break;}}} while (false);if (INVALID_HANDLE_VALUE != hFile){::CloseHandle(hFile);}return FinishHash(bUpper);
}_tstring CCNGHelper::GetDataHash(const void* pData, unsigned long long ullSize,bool bUpper/* = true*/
)
{_tstring strResult;if (m_strAlgorithm.empty()){return strResult;}if (HashData(pData, ullSize)){strResult = FinishHash(bUpper);}return strResult;
}bool CCNGHelper::_HashData(const void* lpData, unsigned long ulSize
)
{// 数据缓冲区上执行单向哈希NTSTATUS status = ::BCryptHashData(m_hHash,(PUCHAR)lpData,ulSize,0);if (!NT_SUCCESS(status)){return false;}return true;
}_tstring CCNGHelper::_BytesToString(const void* lpData, size_t nSize,bool bUpper/* = true*/
)
{const TCHAR rgbDigitsUpper[] = _T("0123456789ABCDEF");const TCHAR rgbDigitsLower[] = _T("0123456789abcdef");_tstring strResult(nSize * 2, 0);LPCBYTE lpBytes = (LPCBYTE)lpData;if (bUpper){for (DWORD i = 0; i < nSize; i++){strResult[i * 2] = rgbDigitsUpper[lpBytes[i] >> 4];strResult[i * 2 + 1] = rgbDigitsUpper[lpBytes[i] & 0x0F];}}else{for (DWORD i = 0; i < nSize; i++){strResult[i * 2] = rgbDigitsLower[lpBytes[i] >> 4];strResult[i * 2 + 1] = rgbDigitsLower[lpBytes[i] & 0x0F];}}return strResult;
}_tstring CCNGHelper::_ToUpper(const _tstring& str
)
{_tstring strResult = str;for (auto& item : strResult){if (item >= _T('a') && item <= _T('z')){item -= 0x20;}}return strResult;
}std::wstring CCNGHelper::_MultiStrToWStr(UINT CodePage, const std::string& str
)
{//计算缓冲区所需的字符长度int cchWideChar = ::MultiByteToWideChar(CodePage, 0, str.c_str(), -1, NULL, NULL);std::wstring strResult(cchWideChar, 0);//成功则返回写入到指示的缓冲区的字符数size_t nConverted = ::MultiByteToWideChar(CodePage, 0, str.c_str(), (int)str.size(), &strResult[0], (int)strResult.size());//调整内容长度strResult.resize(nConverted);return strResult;
}std::wstring CCNGHelper::_TStrToWStr(const _tstring& str
)
{
#ifdef _UNICODEreturn str;
#elsereturn _MultiStrToWStr(CP_ACP, str);
#endif
}

main.cpp

#include <locale.h>
#include <tchar.h>
#include "Win32Utils/CTimeUtils.h"
#include "Win32Utils/CPathUtils.h"
#include "Win32Utils/CCNGHelper.h"int _tmain(int argc, LPCTSTR argv[])
{UNREFERENCED_PARAMETER(argc);UNREFERENCED_PARAMETER(argv);::setlocale(LC_ALL, "");unsigned long long ullStartTime;unsigned long long ullEndTime;CCNGHelper cngObj;cngObj.Initialize(_T("md5"));_tstring strCngHash;_tstring strCryptHash;//system("pause");int nCount = 1000;while (true){ullStartTime = CTimeUtils::GetCurrentTickCount();for (int i = 0; i < nCount; i++){strCngHash = cngObj.GetFileHash(CPathUtils::GetCurrentModulePath(), true);}ullEndTime = CTimeUtils::GetCurrentTickCount();_tprintf(_T("CCNGHelper MD5: %s Cost time: %lld ms\n"), strCngHash.c_str(), ullEndTime - ullStartTime);system("pause");}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/783589.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7种2024年算法优化BP,实现回归,单/多变量输入,单/多步预测功能,机器学习预测全家桶再更新!...

截止到本期MATLAB机器学习预测全家桶&#xff0c;一共发了19篇关于机器学习预测代码的文章。算上这一篇&#xff0c;一共20篇&#xff01;参考文章如下&#xff1a; 1.五花八门的机器学习预测&#xff1f;一篇搞定不行吗&#xff1f; 2.机器学习预测全家桶&#xff0c;多步预测…

wails 创建Go 项目

##wails是一个可以让go和web技术编写桌面应用#安装wails go install github.com/wailsapp/wails/v2/cmd/wailslatest#检查环境 wails doctor 创建项目wails init -n AuxiliaryTools -t vue-ts拉取go.mod的依赖项 go mod tidy进入 frontend 前端安装依赖项npm install /pnpm ins…

自定义微信红包封面小程序,附带后端源码,快速制作个性化红包封面

此小程序适合流量主引流&#xff0c;赚广告费&#xff0c;适合广流量主&#xff0c;适合流量主。 采用云开发&#xff0c;无需服务器&#xff0c;无需域名。小程序里插入banner广告&#xff0c;插屏广告&#xff0c;视频广告&#xff0c;激励式广告。邀请好友获取抽奖机会&…

医院陪诊管理系统(源码+文档)

TOC) 文件包含内容 1、搭建视频 2、流程图 3、开题报告 4、数据库 5、参考文献 6、服务器接口文件 7、接口文档 8、任务书 9、功能图 10、环境搭建软件 11、十六周指导记录 12、答辩ppt模板 13、技术详解 14、前端后台管理&#xff08;管理端程序&#xff09; 15、项目截图 1…

2024中国(杭州)国际数字物流技术与应用展览会将于7月8日举办

2024中国&#xff08;杭州&#xff09;国际数字物流技术与应用展览会 2024年7月8-10日 | 杭州国际博览中心 同期举办&#xff1a;2024长三角快递物流供应链与技术装备展览会 数字贸易创新引领合作动能 《十四五规划》明确指出关于“加快数字化发展&#xff0c;建设数字中国…

代码第三十五天-子集Ⅱ

子集Ⅱ 题目要求 解题思路 回溯法 一般情况下&#xff0c;看到题目要求[所有可能的结果]&#xff0c;而不是[结果的个数]&#xff0c;我们就知道需要暴力搜索所有的可行解了&#xff0c;可以使用[回溯法] 回溯法是一种算法思想&#xff0c;而递归式一种编程方式&#xff0c;回…

Cesium实现渐变面

一、效果图 二、实现思路 使用着色器&#xff0c;通过纹理坐标和其他参数计算出材质的颜色和透明度。通过给定的颜色、漫反射强度和透明度&#xff0c;计算出最终的反射颜色和透明度&#xff0c;并且根据给定的中心点位置和当前像素的纹理坐标&#xff0c;计算出距离中心的距离…

(一)kafka实战——kafka源码编译启动

前言 本节内容是关于kafka消息中间键的源码编译&#xff0c;并通过idea工具实现kafka服务器的启动&#xff0c;使用的kafka源码版本是3.6.1&#xff0c;由于kafka源码是通过gradle编译的&#xff0c;以及服务器是通过scala语言实现&#xff0c;我们要预先安装好gradle编译工具…

每日一练 找无重复字符的最长子串

我们来看下这个题目&#xff0c;我们要统计的是不重复的子串&#xff0c;我们可以使用“滑动窗口法”&#xff0c;其实我们很容易就能想到思路。 我们的左窗代表我们目前遍历的开始&#xff0c;即我们遍历的子串的开头&#xff0c;右窗从左窗开始进行遍历&#xff0c;每次遍历…

【C语言终章】预处理详解(上)

【C语言终章】预处理详解&#xff08;上&#xff09; 当你看到了这里时&#xff0c;首先要恭喜你&#xff01;因为这里就是C语言的最后一站了&#xff0c;你的编程大能旅途也将从此站开始&#xff0c;为坚持不懈的你鼓个掌吧&#xff01; &#x1f955;个人主页&#xff1a;开敲…

04-MySQL数据库-权限管理

一、查看权限 1&#xff0c;查看系统所有权限 mysql> show privileges; 权限字段介绍 privileges #权限名称 context #对象&#xff0c;表示可以对数据库&#xff0c;那些资源、进行哪些操作&#xff1b; comment #描述&#xff0c;备注解释说明&#xff1b; Grant…

Caddy之静态站点应用场景

一、背景与介绍 无意之中看到公司部门的软件介质下载站点不是使用Nginx部署&#xff0c;而是使用Caddy。就比较好奇了&#xff0c;这个Caddy是个什么东西? 为啥他们没用Nginx呢&#xff0c;带着好奇心搜索了一下相关资料。 官方解释: Caddy is a powerful, extensible platfo…

Redis 事务 与 管道

redis事务 谈到事务大家可能就会想起mysql中的事务 注意这里的事务不是指的是事务的四大特性acid 持久性 原子性 隔离性 一致性 事务的概念就是 一组命令,串行化执行而不被打断 这里redis的事务和mysql的事务就不太一样 传统关系型数据库的事务主要强调的是一个没有执行完成就…

neo4j使用详解(六、cypher常用函数语法——最全参考)

Neo4j系列导航&#xff1a; neo4j及简单实践 cypher语法基础 cypher插入语法 cypher插入语法 cypher查询语法 cypher通用语法 cypher函数语法 4.常用函数 主要包括谓词函数&#xff08;断言函数&#xff09;、标量函数、聚合函数、字符串函数以及集合函数 4.1.谓词函数&#…

数据结构--循环链表(C语言实现)

一.循环链表的设计 typedef struct CNode{ int data; struct CNode* next; }CNode ,*CList; 2.循环链表的示意图: 3.循环链表和单链表的区别: 唯一区别,没有空指针,尾节点的后继为头,为循环之意. 二.循环链表的实现 //初始化return true; }//返回key的前驱地址&#xff0c;如果…

Lazarus远控组件NukeSped分析

静态信息&#xff1a; 样本md5&#xff1a;9b656f5d7e679b94e7b91fc3c4f313e4 由此可见为假的Adobe Flash Player 的攻击样本 样本分析 通过五个函数&#xff0c;内部调用sub_40159D函数动态获取API函数 利用IDA python解密字符串。。 完整python代码 Python> idc.get_…

MongoDB副本集环境搭建(以单机Windows为例)

前言 近期有搭建MongoDB副本集的需求,简单记录一下搭建过程(以本地Windows环境为例)。 一、副本集选型 1 Primary节点、1 Secondary 节点、1 Arbiter节点模式副本集环境搭建。 二、搭建过程 1. 安装MongoDB服务 下载地址:https://www.mongodb.com,如下图所示: 选择…

基于Springboot旅游网站管理系统设计和实现

基于Springboot旅游网站管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系…

7.卷积神经网络与计算机视觉

计算机视觉是一门研究如何使计算机识别图片的学科&#xff0c;也是深度学习的主要应用领域之一。 在众多深度模型中&#xff0c;卷积神经网络“独领风骚”&#xff0c;已经被称为计算机视觉的主要研究根据之一。 一、卷积神经网络的基本思想 卷积神经网络最初由 Yann LeCun&a…

UE4_碰撞_自定义碰撞检测通道

效果如图&#xff1a; 1、项目设置中新建追踪检测通道weapon&#xff0c;默认值为忽略。 2、新建几个actor作为枪&#xff0c;碰撞预设全部设为自定义&#xff0c;把新建的检测响应weapon设为阻挡。 3、角色进行射线检测 运行效果如下&#xff1a; 发现有些物体碰不到&#xff…