在实际应用中,客户可能希望对自己的程序添加验证过程,使得无法被随意拷贝到其它板子上使用。英创ARM系列工控主板都配有唯一指定MAC,我们可以根据MAC地址,生产加密字符串,存入KEY文件或是注册表内。然后在程序启动部分添加验证代码,验证这个字符串,从而达到防拷贝的目的。
本文介绍MAC的获得方式及几种常用的加密方式。
验证设备
在验证MAC之前,首先应当检查使用的板卡型号,以检查EM9281为例,代码如下。
添加头文件及宏定义,此部分代码均包含在板子对应SDK包中的bsp_drivers.h下
#include <winioctl.h>
extern "C" __declspec(dllimport) BOOL KernelIoControl( DWORD dwIoControlCode,
LPVOID lpInBuf,
DWORD nInBufSize,
LPVOID lpOutBuf,
DWORD nOutBufSize,
LPDWORD lpBytesReturned);
#define IOCTL_HAL_BOARD_STATE_READ CTL_CODE(FILE_DEVICE_HAL, 4024, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define EM9280_BOARD_TYPE_9280 0
#define EM9280_BOARD_TYPE_9281 1 // -> EM9281
#define EM9280_BOARD_TYPE_9380 2
#define EM9280_BOARD_TYPE_9283 3
#define EM9280_BOARD_TYPE_ES9281 4 // -> ES9281
#define EM9280_BOARD_TYPE_9287 7
#define EM9280_BOARD_CFG_SHIFT 14
#define EM9280_BOARD_CFG_MASK 0x3
#define EM9280_BOARD_TYPE_SHIFT 4
#define EM9280_BOARD_TYPE_MASK 0x7
#define EM928X_BOARD_TYPE_BASE(v) ((v >> EM9280_BOARD_TYPE_SHIFT) & EM9280_BOARD_TYPE_MASK)
#define EM928X_BOARD_TYPE_SUB_ID(v) ((v >> EM9280_BOARD_CFG_SHIFT) & EM9280_BOARD_CFG_MASK)
#define EM9287_BOARD_TYPE_SUB_TYPE(v) ((EM928X_BOARD_TYPE_SUB_ID(v)==1)? EM9280_BOARD_TYPE_9281:\
(EM928X_BOARD_TYPE_SUB_ID(v)==2)? EM9280_BOARD_TYPE_ES9281: EM9280_BOARD_TYPE_9287)
#define EM928X_BOARD_TYPE_ALL(v) ((EM928X_BOARD_TYPE_BASE(v)==EM9280_BOARD_TYPE_9287)? EM9287_BOARD_TYPE_SUB_TYPE(v):EM928X_BOARD_TYPE_BASE(v))
检查板卡型号,以EM9281为例
BOOL bRet;
DWORD dwReturnBytes;
DWORD dwBoardInfo = 0;
dwReturnBytes = 0;
bRet = KernelIoControl(IOCTL_HAL_BOARD_STATE_READ,
NULL, 0,
(LPVOID)&dwBoardInfo, sizeof(DWORD),
&dwReturnBytes);
If(EM928X_BOARD_TYPE_ALL(dwBoardInfo)!= EM9280_BOARD_TYPE_9281) return;
获得MAC地址
必要的头文件和lib库
#include "Iphlpapi.h"
#pragma comment(lib,"Iphlpapi.lib")
VOID GetMAC(BYTE* buf)
{
DWORD dwRetVal;
IP_ADAPTER_INFO AdapterInfo[4];
ULONG OutBufLen = sizeof(IP_ADAPTER_INFO);
GetAdaptersInfo(&AdapterInfo[0], &OutBufLen);
GetAdaptersInfo(&AdapterInfo[0], &OutBufLen);
/*if(strcmp(AdapterInfo[0].AdapterName, "ENET1") != 0)
{
return;
}*/
memcpy(buf, AdapterInfo[0].Address, 6);
}
BYTE mac[6];
GetMAC(mac);
char macstr[16];
sprintf(macstr, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
加密策略
英创所有嵌入式板卡都拥有唯一的MAC地址,在对MAC地址加密后,生成唯一的加密KEY。同时程序中判断板卡信息,并验证这个加密KEY。这样可以保证程序必须处于正确的板卡中,并拥有正确的KEY文件,才能执行。
为了增加安全性,加大KEY文件破译难度,可以考虑以下处理
1、将MAC地址与常量字符串混合后,再进行加密,生成加密KEY。
2、多种加密手段结合使用,多次加密。
3、验证失败后“软”关闭程序,可以做延迟处理,并可以考虑重启设备,增加暴力破解KEY的难度。
加密程序流程
获得板卡MAC地址 à 执行加密函数 à 生成KEY文件置入板卡中
解密程序流程
查询板卡MAC à 执行加密函数 à 读取KEY文件中密钥并对比 à 判断验证是否成功并进行后续执行
或
读取KEY文件中密钥 à 执行解密函数 à 查询板卡MAC并对比 à 判断验证是否成功并进行后续执行
加密方法
常用的加密方法有很多,可以参考文章《常用加密方法及代码》。同时英创提供这些加密算法相关测试例程,如有需要,可以联系英创工程师获得。
成都英创信息技术有限公司 028-8618 0660