针对MAC地址的应用程序加密方法

 2014-7-31         

  在实际应用中,客户可能希望对自己的程序添加验证过程,使得无法被随意拷贝到其它板子上使用。英创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);

  IfEM928X_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并对比 à 判断验证是否成功并进行后续执行


加密方法


  常用的加密方法有很多,可以参考文章《常用加密方法及代码》。同时英创提供这些加密算法相关测试例程,如有需要,可以联系英创工程师获得。