ET199加密方案——文件MD5校验
来源:互联网 发布:南京泛成生物 知乎 编辑:程序博客网 时间:2024/06/06 15:46
ET199(http://www.jansh.com.cn/product/detail.php?cid=13)采用安全强度最高的智能卡芯片,硬件不能被复制,多重安全级别,并且集成了16位CPU,8KRAM,64K存储空间等模块。运行在ET199内部的程序是使用C51语言进行开发的,本方案示例主要用到MD5计算的内部系统函数,通过内部MD5计算对程序添加校验。方案的测试过程需要首先在ET199加密锁中预先设置公私钥文件和一个可执行文件,详见ET199内部文件配置。
方案原理说明:
本方案示例,通过调用内部系统函数,将源程序除去最后16个字节二进制文件做MD5散列运算,将运算的结果保存到二进制文件的最后16个字节中,每次程序运行时,程序通过加密锁内部MD5计算对自身做MD5运算校验,如果程序被修改了,那么运算之后的结果一定与之前的的校验结果不相同,则说明程序被改动过,如果运算之后的结果与之前保存的结果相同,那么说明源程序没有被修改过。
方案示例:
本说明文档中仅列举核心代码或函数,详细的代码设计,请参看方案源代码。所有操作均在插有ET199加密锁的状态下完成,并且加密锁属性都是出厂默认设置。本方案示例将需要重复使用的枚举ET199、打开ET199等函数封装到一个函数:
DWORD CMD5FileCheckDlg::OpenDog(ET_CONTEXT* pETC)
{
DWORD dwRet;
DWORD dwCount;
ET_CONTEXT *pContext;
//===============================
//枚举ET199并返回数量
dwCount = 0;
dwRet = ETEnum(NULL,&dwCount);
if(dwRet != ET_E_INSUFFICIENT_BUFFER && dwRet != ET_S_SUCCESS) return dwRet;
//根据数量分配内存用于存储CONTEXT结构数组
pContext = new ET_CONTEXT[dwCount];
//清0缓冲区
memset(pContext,0,sizeof(ET_CONTEXT)*dwCount);
//使用分配的缓冲区重新进行枚举
dwRet=ETEnum(pContext,&dwCount);
if(dwRet != ET_S_SUCCESS) return dwRet;
if(dwCount == 0) return ET_E_KEY_REMOVED;
//打开ET199
dwRet = ETOpen(&pContext[0]);
if(dwRet != ET_S_SUCCESS) return dwRet;
* pETC = pContext[0];
return ET_S_SUCCESS;
}
将执行过程封装到函数:
DWORD CMD5FileCheckDlg::ExecuteDog(ET_CONTEXT* pETC, LPCSTR lpszFileID, BYTE* pInbuf, int len_In, BYTE* pOutbuf, int* len_Out)
{
DWORD leng;
DWORD dwRet;
BYTE tmpbuf[256];
// =================
//检查加密锁句柄
if(pETC->hLock == INVALID_HANDLE_VALUE) return -1;
//
memset(tmpbuf, 0, sizeof(tmpbuf));
//执行芯片中的1000可执行文件
dwRet = ETExecute(pETC, lpszFileID, pInbuf, len_In, pOutbuf, *len_Out, &leng);
if(dwRet != ET_S_SUCCESS) return dwRet;
//tmpbuf[0]是芯片中代码执行的返回值
if(tmpbuf[0] != 0) //ET_SUCCESS
{
return tmpbuf[0];
}
//返回数据
*len_Out = leng;
return 0;
}
以上两个函数的封装,仅是为了方便起见。
一、运行MD5FileMake.exe,该程序实现对某一程序添加MD5校验
图1
选择需要添加检验的源程序MD5FileCheck.exe,单击“MD5固化文件”,会在相应目录下产生一个校验文件ChangeLess.exe。
//校验MD5
BOOL CMD5FileCheckDlg::MakeFileMD5(char* pFilePath)
{
HANDLE handle;
long file_len;
BYTE* pbuf;
DWORD bytesread;
//==================
//打开文件
handle=CreateFile(pFilePath,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(handle == INVALID_HANDLE_VALUE)
{
return FALSE;
}
file_len = GetFileSize(handle, 0);
pbuf = (BYTE*)malloc(file_len);
ReadFile(handle, pbuf, file_len, &bytesread, 0);
CloseHandle(handle);
GetTrueMD5(pbuf, file_len-16, pbuf+file_len-16);
handle=CreateFile("ChangeLess.exe", GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
if(handle == INVALID_HANDLE_VALUE)
{
free(pbuf);
//
return FALSE;
}
WriteFile(handle, pbuf, file_len, &bytesread, 0);
CloseHandle(handle);
free(pbuf);
return TRUE;
}
二、二进制文件的比较
源程序二进制文件和检验程序二进制文件的比较如下图所示,其中图1是源程序MD5FileCheck.exe最后16个字节的二进制,图3是检验文件ChangeLess.exe的最后16字节的二进制。
图2
图3
三、运行添加校验的程序ChangeLess.exe
图4
该程序实现对自身的检验,单击“校验文件MD5值”如果源程序没有被修改过,运行检验程序时会提示“文件完整性检验OK”。
图5
如果源程序被修改过,运行校验文件是则会提示“文件完整新检验ERR”。
图6
//校验MD5
BOOL CMD5FileCheckDlg::CheckFileMD5(char* pFilePath)
{
HANDLE handle;
long file_len;
BYTE* pbuf;
DWORD bytesread;
BYTE TrueMD5[16];
BYTE FileMD5[16];
//==================
//打开文件
handle=CreateFile(pFilePath,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(handle == INVALID_HANDLE_VALUE)
{
return FALSE;
}
file_len = GetFileSize(handle, 0);
pbuf = (BYTE*)malloc(file_len);
ReadFile(handle, pbuf, file_len, &bytesread, 0);
CloseHandle(handle);
memset(TrueMD5, 0, sizeof(TrueMD5));
GetMD5(pbuf, file_len-16, TrueMD5);
memcpy(FileMD5, pbuf+file_len-16, 16);
free(pbuf);
if(memcmp(FileMD5, TrueMD5, 16) == 0) return TRUE;
else return FALSE;
}
//MD5计算
void CMD5FileCheckDlg::GetMD5(BYTE* pbuf, long len, BYTE* pOutMD5)
{
int leng;
DWORD dwRet;
ET_CONTEXT etc;
BYTE tmpbuf[1+128];
BYTE md5[16];
// =================
//打开加密锁
if(OpenDog(&etc) != ET_S_SUCCESS)
{
AfxMessageBox("打开加密锁失败!");
return;
}
//校验PIN码
if(ETVerifyPin(&etc, ET_DEFAULT_USER_PIN, ET_USER_PIN_LEN, ET_USER_PIN) != ET_S_SUCCESS)
{
AfxMessageBox("加密锁校验用户PIN码失败!");
return;
}
//文件128字节块xor
XorBlock128(pbuf, len, tmpbuf+1);
//执行芯片中的1000可执行文件,功能号:MD5运算
tmpbuf[0] = Func_MD5;
leng = sizeof(tmpbuf);
dwRet = ExecuteDog(&etc, "1000", tmpbuf, sizeof(tmpbuf), tmpbuf, &leng);
if(dwRet == 0 && tmpbuf[0] == 0)
{
//返回数据
memcpy(md5, tmpbuf+1, 16);
}
else
{
AfxMessageBox("执行加密锁内算法失败!");
//关闭加密锁
ETClose(&etc);
return;
}
memcpy(pOutMD5, md5, 16);
//关闭加密锁
ETClose(&etc);
return;
}
方案特点:
本加密方案的设计,首先通过对一个文件添加MD5校验,然后每次运行程序师通过该文件自身做一次MD5的校验,如果程序有一点的“风吹草动”,那么校验值一定同之前存储的校验值是不一样的,从而可以判断文件是否被修改过,以此可以有效验证源程序是否被破解者恶意篡改。
- ET199加密方案——文件MD5校验
- ET199加密方案——用户注册机制
- iOS文件的MD5校验--大文件的MD5加密
- MD5工具类,提供字符串MD5加密(校验)、文件MD5值获取(校验)功能
- MD5工具类,提供字符串MD5加密(校验)、文件MD5值获取(校验)功能
- 使用ET199加密锁存储TrueCrypt的密钥文件
- md5 校验和加密
- C#实现字符串,文件获取Md5加密校验方法
- 79 MD5加密方案
- C# MD5文件校验
- C# MD5文件校验
- C# MD5文件校验 .
- MD5 生成文件校验
- MD5文件校验
- MD5文件校验
- 文件的MD5校验
- MD5 生成文件校验
- 文件做MD5校验
- 基本代码知识
- 使用Catalog或者ArcGIS Manager创建Map Cache(切片)
- jquery AJAX的两注册方式
- jquery贪食蛇游戏
- FSO组件之文件夹操作
- ET199加密方案——文件MD5校验
- SQL 读取循环读取文件夹里面所有指定内容
- 搜索引擎爬虫的基本需求和考核标准
- 哈佛有一个著名的理论
- spring中的ref标签
- TCP/IP 详解 卷1:协议
- 标准C函数的一些字符串与整型、浮点型的转换
- Wince 系统内存
- 使用ASP更改 NTFS 分区中 文件夹的 读写等权限