Unique ID加密原理
當(dāng)前市面上的單片機(jī)資源中大多數(shù)具有Unique ID,即每一個(gè)芯片內(nèi)部均具有唯一的芯片ID號(hào)。不同的芯片廠家實(shí)現(xiàn)該功能的方式不同,一些用生產(chǎn)線的流水號(hào),另一些是用晶圓的特性來生成ID。 利用Unique ID加密的方法流程如下:
加密算法
為了防止破解者通過仿真的方式找到芯片ID信息,一般不宜直接存放ID號(hào)。而是經(jīng)過相應(yīng)的加密處理后寫入存儲(chǔ)器中。校驗(yàn)方式也不宜采用常見、簡(jiǎn)單的校驗(yàn)規(guī)則,應(yīng)盡可能采用某些特殊的檢驗(yàn)方式,使破解者不能迅速確定校驗(yàn)算法。
加密的算法類似數(shù)學(xué)公式 Y=F(X)
其中Y為加密以后的數(shù)據(jù),X為原始數(shù)據(jù),而F則為加密算法。
加密算法有很多種,本實(shí)驗(yàn)中采用簡(jiǎn)單的位移后取反的方式來進(jìn)行數(shù)據(jù)加密。
最后將加密的數(shù)據(jù)存入EEPROM中,由于芯片的ID廠家不允許更改,這大大增加了破解難度,加強(qiáng)了對(duì)產(chǎn)品的保護(hù)。
詳細(xì)設(shè)計(jì)過程
使用Unique ID對(duì)單片機(jī)程序加密功能的實(shí)現(xiàn)需要以下幾點(diǎn)功能:
① 實(shí)驗(yàn)板1用于對(duì)程序加密實(shí)驗(yàn)。
② 將從實(shí)驗(yàn)板1中讀取到的數(shù)據(jù)燒錄到實(shí)驗(yàn)板2中,通過實(shí)驗(yàn)板上的LED狀態(tài)驗(yàn)證程序加密是否成功。
基于Unique ID的單片機(jī)程序加密分為2個(gè)程序,這2個(gè)程序是不同的。
程序A:用于讀取芯片硬件ID并進(jìn)行算法處理,將處理后的數(shù)據(jù)保存到EEPROM中。
程序B:用于將EEPROM中的數(shù)據(jù)讀取出來并使用與加密相同的算法進(jìn)行解密獲得芯片ID,將解密后獲得的ID與芯片本身的ID進(jìn)行比較。比較結(jié)果只有2種可能,即為相同與不同,程序根據(jù)結(jié)果從而執(zhí)行不同的操作如圖所示;
實(shí)驗(yàn)中使用STM8S單片機(jī)作為硬件載體
軟件設(shè)計(jì)
系統(tǒng)初始化函數(shù)選擇了內(nèi)部16MHz時(shí)鐘源,1分頻后系統(tǒng)總線時(shí)鐘頻率為16MHz。
將GPIO與EEPROM擦寫均進(jìn)行了初始化配置。 函數(shù)代碼如下:
LED驅(qū)動(dòng)程序
根據(jù)硬件的電路原理圖可以看出,LED連接到PE5引腳。采用灌電流驅(qū)動(dòng),當(dāng)引腳為低電平時(shí)LED點(diǎn)亮,引腳為高電平時(shí)LED熄滅。上電后LED默認(rèn)為熄滅狀態(tài),所以引腳初始化配置為高速輸出模式高電平。函數(shù)代碼如下:
/*描述:MCU外圍GPIO初始化*//*輸入:無*/void Gpio_Init(vod){ //功能引腳上電初始化,引腳初始化狀態(tài)根據(jù)外部功能而定義// GPIO_Init(GPIOE, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST); //LED}LED的狀態(tài)采用宏定義方式,直接控制IO管腳電平狀態(tài)。 操作代碼如下:
/*LED操作宏定義*/#define LED_ON GPIO_WriteLow(GPIOE, GPIO_PIN_5); //點(diǎn)亮LED#define LED_OFF GPIO_WriteHigh(GPIOE, GPIO_PIN_5); //熄滅LED獲取Unique ID程序
STM8S105K4T6數(shù)據(jù)手冊(cè)顯示該芯片具有96bit Unique ID,96bit/8=12byte。存放ID的起始地址為0x48CD,從該地址讀取12次,將芯片ID獲取并存入數(shù)組。 函數(shù)代碼如下:
/*描述:獲取芯片ID*//*輸入:存放芯片ID的數(shù)組*//*輸出:無*//*參數(shù):無*/void Get_ChipID(unsigned char *p)//Get chip ID{ unsigned char i=0; for(i=0; i<12; i++) //讀取12次 { *p = *(u8*)(0X48CD+i); //將數(shù)據(jù)讀出后進(jìn)行存放 p++; }}加密算法程序
編碼函數(shù)執(zhí)行對(duì)Unique ID進(jìn)行數(shù)據(jù)算法處理。實(shí)驗(yàn)中采用的算法為將存放Unique ID的數(shù)組進(jìn)行左移三個(gè)元素后逐位取反。將編碼后的數(shù)據(jù)存入另一個(gè)數(shù)組。
編碼函數(shù)代碼如下:
解密算法程序
解碼函數(shù)負(fù)責(zé)對(duì)從EEPROM中讀取的數(shù)據(jù)進(jìn)行解碼,是編碼函數(shù)的一個(gè)逆向算法處理。算法為將輸入的數(shù)組(EEPROM數(shù)據(jù))進(jìn)行右移三個(gè)元素后按位取反。示意圖如下:
函數(shù)如下
/*描述:對(duì)從EEPROM讀出的數(shù)據(jù)進(jìn)行解碼*//*輸入:存放編碼數(shù)據(jù)的數(shù)組,存放解碼數(shù)據(jù)的數(shù)組*//*輸出:無*//*參數(shù):數(shù)據(jù)右移三位后按位取反(算法)*/void Decode(unsigned char *DataIn,unsigned char *DataOut){ unsigned char i;//數(shù)組數(shù)據(jù)左移次數(shù) unsigned char j;//數(shù)據(jù)位移臨時(shí)局部變量 unsigned char DataSwap;//搬運(yùn)數(shù)據(jù)用的臨時(shí)變量 unsigned char TempData[12];//數(shù)據(jù)處理交換變量數(shù)組 for(i=0;i<12;i++)//數(shù)據(jù)數(shù)組交換 { TempData = *DataIn; DataIn++; } for(i=0;i<3;i++)//數(shù)據(jù)右移三次 { //數(shù)組元素右移操作 DataSwap = TempData[11]; for(j=10;j>0;j--)//數(shù)組右移搬運(yùn) { TempData[j+1] = TempData[j]; } TempData[1] = TempData[0]; TempData[0] = DataSwap;//最后一次搬運(yùn) } for(i=0;i<12;i++)//對(duì)數(shù)組數(shù)據(jù)進(jìn)行諸位取反 { TempData = ~ TempData ; *DataOut = TempData; DataOut ++; }}數(shù)據(jù)寫入EEPROM程序
將編碼處理后的數(shù)據(jù)寫入EEPROM,存儲(chǔ)器起始地址為0x000040A0,通過單字節(jié)寫入。將12個(gè)字節(jié)全部寫入EEPROM。函數(shù)代碼如下:
/*描述:EEPROM數(shù)據(jù)寫入*//*輸入:數(shù)據(jù)源的數(shù)組*//*輸出:無*//*參數(shù):無*/void EEPROMWrite(unsigned char *p){ unsigned char i;//數(shù)據(jù)交換用局部臨時(shí)變量 FLASH_Unlock(FLASH_MEMTYPE_DATA); //解鎖EEPROM,允許寫入數(shù)據(jù) while( !(FLASH_GetFlagStatus(FLASH_FLAG_DUL)) );//等待EEPROM解鎖完成 for(i=0;i<12;i++) { FLASH_ProgramByte(0x000040A0+i, *p);//將數(shù)據(jù)寫入EEPROM,寫入存儲(chǔ)起始地址為0x000040A0 while( !( FLASH_GetFlagStatus(FLASH_FLAG_EOP)) );//等待EEPROM單次寫入完成 p++; } FLASH_Lock(FLASH_MEMTYPE_DATA); //鎖定EEPROM}從EEPROM讀出數(shù)據(jù)程序
程序首先需要從EEPROM中讀取加密后的數(shù)據(jù),將數(shù)據(jù)保存到數(shù)組EncodeData中。程序代碼如下:
/*描述:讀取芯片EEPROM數(shù)據(jù)*//*輸入:用于存放EEPROM的數(shù)組*//*輸出:無*//*參數(shù):*/void Get_EEPROMData(unsigned char *p){ unsigned char i=0; for(i=0; i<12; i++) { *p = FLASH_ReadByte(0x40A0 + i);//從EEPROM讀取數(shù)據(jù) p++; }}數(shù)據(jù)比對(duì)程序
數(shù)據(jù)比對(duì)函數(shù)負(fù)責(zé)將解密后數(shù)據(jù)與Unique ID兩個(gè)數(shù)組的數(shù)據(jù)進(jìn)行比對(duì)。該函數(shù)只有兩個(gè)返回結(jié)果,數(shù)據(jù)完全相同與不同,返回不同的值。根據(jù)不同的返回值從而判斷程序是否合法。函數(shù)代碼如下:
/*描述:將兩個(gè)數(shù)據(jù)進(jìn)行比對(duì)*//*輸入:要比對(duì)的數(shù)據(jù)A,要比對(duì)的數(shù)據(jù)B*//*輸出:比對(duì)結(jié)果 1:數(shù)據(jù)相同 0:數(shù)據(jù)不同*//*參數(shù):對(duì)數(shù)組進(jìn)行按字節(jié)比對(duì)*/unsigned char IDCheck(unsigned char *a,unsigned char *b){ unsigned char i; unsigned char Flag;//比對(duì)結(jié)果標(biāo)志 1:數(shù)據(jù)相同 0:數(shù)據(jù)不同 Flag = 1; for(i=0;i<12;i++) { if( (*a) != (*b) ) { Flag = 0; } a++; b++; } return Flag;//返回值:比對(duì)結(jié)果標(biāo)志 1:數(shù)據(jù)相同 0:數(shù)據(jù)不同}數(shù)據(jù)數(shù)組
使用數(shù)組的存儲(chǔ)芯片ID與編碼加密后的數(shù)據(jù)。代碼如下:
A程序主函數(shù)代碼
本程序主要作用是將數(shù)據(jù)進(jìn)行加密編碼處理并將結(jié)果寫入EEPROM, 程序的主函數(shù)調(diào)用上方的單元功能函數(shù)。
運(yùn)行該程序后,將讀取到的芯片ID數(shù)據(jù)存入數(shù)組。通過內(nèi)部編碼算法函數(shù)將ID進(jìn)行處理并寫入EEPROM。程序運(yùn)行流程圖如圖所示:
B程序主函數(shù)代碼
程序B作用為對(duì)EEPROM數(shù)據(jù)讀取并進(jìn)行解碼處理后判斷程序合法性。主函數(shù)代碼如下:
解碼程序?yàn)樽罱K燒錄到芯片中的程序,產(chǎn)品功能也是在次此結(jié)構(gòu)下開發(fā)的。程序執(zhí)行后會(huì)讀取當(dāng)前芯片自身的Unique ID與存儲(chǔ)在EEPROM中的數(shù)據(jù)。將EEPROM中的數(shù)據(jù)進(jìn)行解碼后與Unique ID進(jìn)行比對(duì),當(dāng)數(shù)據(jù)完全相同時(shí)判斷程序合法并執(zhí)行正常程序功能,當(dāng)數(shù)據(jù)比對(duì)不相同后判斷程序非法并執(zhí)行相應(yīng)操作。解碼程序運(yùn)行流程圖如圖所示:
系統(tǒng)測(cè)試
將運(yùn)行B程序后的實(shí)驗(yàn)板1通過通過仿真器與電腦連接,將STVP切換到“Program Memory”選項(xiàng)卡后點(diǎn)擊“Read curren tab of active sectors”按鈕后讀取數(shù)據(jù)。在菜單File->save中選擇保存程序B。(模擬程序被解密)
將讀取的程序B燒錄到實(shí)驗(yàn)板2中,觀察LED的現(xiàn)象。
燒錄程序B后實(shí)驗(yàn)板1測(cè)試LED亮起,實(shí)驗(yàn)板2測(cè)試LED未亮起。
測(cè)試結(jié)果
從實(shí)驗(yàn)中可以看到,實(shí)驗(yàn)板二雖然燒錄了程序B,但是之前并沒有運(yùn)行過程序A的加密算法,所以程序識(shí)別出EEPROM解密后數(shù)據(jù)與芯片自身ID不匹配從而熄滅LED。
本文所設(shè)計(jì)的系統(tǒng)已經(jīng)通過上述過程的測(cè)試,可以滿足對(duì)單片機(jī)程序加密的功能需求。
當(dāng)前加密系統(tǒng)中需要完善的部分
程序中僅僅有1處判斷程序合法性,一旦遭到反編譯后容易被破解
程序被判斷為非法后沒有保護(hù)操作,應(yīng)加入強(qiáng)制擦除 Flash進(jìn)行保護(hù)
程序需要燒錄2次來完成整個(gè)加密系統(tǒng)的流程. 應(yīng)在程序中加入啟動(dòng)加密條件,實(shí)現(xiàn)一次程序燒錄即可完成加
| 歡迎光臨 (http://www.raoushi.com/bbs/) | Powered by Discuz! X3.1 |