通过前面的文章,我们已经掌握了如下5项技术:
现在我将综合这5项技术,通过配置文件实现多个软件对多个硬件的加密。其实现思路如下:
开发语言:Visual C++
支持平台:Windows
实现功能:采用配置文件实现多个软件对多个硬件的加密
下载地址:
DeviceQuery.zip
版本历史:
V1.5 2010年05月24日
- 改进配置文件设计。
V1.4 2010年05月11日
- 密文采用BASE64编码输出。
V1.3 2010年04月30日
- 修正微软MSDN例子错误,并增加对虚拟网卡的判断。
V1.2 2010年04月27日
- 加入WMI查询。
V1.1 2010年04月21日
- 改进配置文件设计。
V1.0 2010年04月15日
完成正式版本,具备WDK查询。
接口函数:
INI_DeviceQuery
配置文件格式:
;人机交互设备(VID-PID=dwKey|HMAC) [HID] MODE=WDK TYPE=0 046D-C315=0x00000012|Mo3hF5lC8sAWhKHdwvT16g== 046D-C52B=0x00000012|ViJPd8F8tawxfnzT6R2TLQ== ;网卡原生MAC地址 [NIC-PA] MODE=WDK TYPE=1 6CF049007689=0x00000020|9Vw9VDxuQIQIP/A+171AZw== 002719AA763A=0x00000020|p84cf1r55foKEm2qzkmEaw== ;硬盘序列号 [HARDDISK] MODE=WMI TYPE=1 V90XHAT2=0x00000040|WrZMdQZbBXFKM8m0JRxPkg== N9CBZ0TY=0x00000040|ayyn1kGrK9GhAX1/8NH3Iw== ;主板序列号 ;[BASEBOARD-SN] ;MODE=WMI ;TYPE=2 ;CPU ID ;[CPU] ;MODE=WMI ;TYPE=3 ;BIOS序列号 ;[BIOS] ;MODE=WMI ;TYPE=4 ;主板型号 [BASEBOARD-MODEL] MODE=WMI TYPE=5 P55A-UD3R=0x0000000F|f3dVTbLWaiCyM+iWfP1vnA==
源代码:
INI_DeviceQuery.h
/* ---------------------------------------------------------- 文件名称:INI_DeviceQuery.h 作者:秦建辉 MSN:[email protected] 版本历史: V1.5 2010年05月24日 改进配置文件设计。 V1.4 2010年05月11日 密文采用BASE64编码输出。 V1.3 2010年04月30日 修正微软MSDN例子错误,并增加对虚拟网卡的判断。 V1.2 2010年04月27日 加入WMI查询。 V1.1 2010年04月21日 改进配置文件设计。 V1.0 2010年04月15日 完成正式版本,具备WDK查询。 功能描述: 采用配置文件实现对各种硬件加密 接口函数: INI_DeviceQuery ------------------------------------------------------------ */ #pragma once #include <windows.h> // 回调函数,用于校验明文密文是否匹配 typedef BOOL (CALLBACK* FP_HMAC_Verify)( const TCHAR* szPlainText, const TCHAR* szCipherText ); // 回调函数,用于打印 typedef void (CALLBACK* FP_Show_DeviceKey)( const TCHAR* szDeviceKey ); #ifdef __cplusplus extern "C" { #endif /* 功能:获取授权产品列表 参数说明: iniFileName:授权产品配置文件名 fp_Verify:回调函数,用于数据校验,防止信息篡改。如果为NULL,则使用内部的校验函数。 fp_Show:回调函数,调试分析时用于获取更具体信息。正式使用时设为NULL。 返回值: 授权产品总列表 */ DWORD INI_DeviceQuery( const TCHAR* iniFileName, FP_HMAC_Verify fp_Verify = NULL, FP_Show_DeviceKey fp_Show = NULL ); #ifdef __cplusplus } #endif
INI_DeviceQuery.cpp
#include "INI_DeviceQuery.h" #include "..//WDK_DeviceQuery//WDK_DeviceQuery.h" #include "..//WMI_DeviceQuery//WMI_DeviceQuery.h" #include "..//HMACMD5//HMAC_MD5_API.h" #include "..//RWINIFILE//RWINIFILE.h" #include <tchar.h> #include <strsafe.h> // 判断明文密文是否匹配 static BOOL __stdcall HMACMD5_Verify( const TCHAR* szPlainText, const TCHAR* szCipherText ) { const TCHAR* secretKey = TEXT("大梦谁先觉?平生我自知。草堂春睡足,窗外日迟迟。"); // 加密密钥 TCHAR hmacCipher[32]; INT iLen; // 计算明文的哈希值 iLen = HMAC_MD5_BASE64( reinterpret_cast<const BYTE*>(szPlainText), _tcslen( szPlainText ) * sizeof(TCHAR), reinterpret_cast<const BYTE*>(secretKey), _tcslen(secretKey) * sizeof(TCHAR), hmacCipher ); // 将密文文本和校验码进行比对 if( _tcsncmp( hmacCipher, szCipherText, iLen ) == 0 ) { return TRUE; } else { return FALSE; } } DWORD INI_DeviceQuery( const TCHAR* iniFileName, FP_HMAC_Verify fp_Verify, FP_Show_DeviceKey fp_Show ) { TCHAR szSectionNames[1024]; // 存储所有的分区名 TCHAR szKeyValue[64]; // 存储键值及校验字符串“KEY|HMAC” TCHAR szPlainText[80]; // 存储去掉校验字符串后的“VID-PID=KEY” TCHAR *pDest; UINT uIndex; DWORD dwSubKey, dwAllKey = 0; CRWINIFILE iniFile; // 如果校验函数为空,则使用缺省校验函数 if( fp_Verify == NULL ) { fp_Verify = HMACMD5_Verify; } // 读取授权产品配置文件 if( !iniFile.LoadFile( iniFileName, GENERIC_READ, 0, TRUE ) ) { return 0; } // 获取产品分类 if( iniFile.GetProfileSectionNames( szSectionNames, sizeof(szSectionNames)/sizeof(TCHAR) ) > 0 ) { for( uIndex = 0; szSectionNames[uIndex] != 0; uIndex += _tcslen( szSectionNames + uIndex ) + 1 ) { TCHAR szMode[16]; INT iQueryType; // 获取查询类型 iQueryType = iniFile.GetProfileInt( szSectionNames + uIndex, TEXT("TYPE"), -1 ); // 获取查询方式(WDK查询还是WMI查询) if( iniFile.GetProfileString( szSectionNames + uIndex, TEXT("MODE"), NULL, szMode, sizeof(szMode)/sizeof(TCHAR) ) > 0 ) { T_DEVICE_PROPERTY properties[32]; INT iDevNum = 0; if( _tcsicmp( szMode, TEXT("WDK") ) == 0 ) { iDevNum = WDK_DeviceQuery_Property( iQueryType, properties, sizeof(properties)/sizeof(T_DEVICE_PROPERTY) ); } else if( _tcsicmp( szMode, TEXT("WMI") ) == 0 ) { iDevNum = WMI_DeviceQuery( iQueryType, properties, sizeof(properties)/sizeof(T_DEVICE_PROPERTY) ); } for( INT i = 0; i < iDevNum; i++ ) { if( iniFile.GetProfileString( szSectionNames + uIndex, properties[i].szProperty, NULL, szKeyValue, sizeof(szKeyValue)/sizeof(TCHAR) ) > 0 ) { // 查找分隔符 pDest = _tcschr( szKeyValue, TEXT('|') ); if( pDest != NULL ) { // 析取授权产品列表 *pDest++ = TEXT('/0'); StringCchPrintf( szPlainText, sizeof(szPlainText)/sizeof(TCHAR), TEXT("%s=%s"), properties[i].szProperty, szKeyValue ); // 回调函数,对数据一致性做校验 if( fp_Verify( szPlainText, pDest ) ) { dwSubKey = _tcstoul( szKeyValue, NULL, 0 ); dwAllKey |= dwSubKey; // 回调函数获取具体信息 if( fp_Show != NULL ) { fp_Show( szPlainText ); } } } } } // End for i } } // End for uIndex } iniFile.CloseFile(); return dwAllKey; }