新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 只要單片機具有真正唯一ID,就可以讓加密堅不可摧

只要單片機具有真正唯一ID,就可以讓加密堅不可摧

作者: 時間:2016-11-25 來源:網(wǎng)絡(luò) 收藏
第一環(huán):


ID-->F1(ID) -----》IDX,

將ID通過自定義的一個算法F1,轉(zhuǎn)換為一個整數(shù)IDX , F1為不可逆運算,也不能被輕易分析,這個實際上是容易實現(xiàn)的。

然后,將IDX保存到EEPROM或FLASH的任何地方,我們通過編一個函數(shù) GET_IDX()能夠讀出這個數(shù)即可。


第二環(huán):

再編一個函數(shù):

int getmy_1(){
return F1(ID)-GET_IDX()+1;
}

int getmy_0(){
return F1(ID)-GET_IDX();
}


還有一些其他自定義的函數(shù)內(nèi):都可以直接使用(F1(ID)-GET_IDX()) 來替代0; 直接用(F1(ID)-GET_IDX()+1)來替代1;


第三環(huán):

在程序任何需要使用到1的地方,都可以考慮使用getmy_1()代替。

或即使本不使用1,也可以來用上一下:

如: x=(x+1-getmy_1())*getmy_1();


或把 for(i=0;i<=count-1;i++)
改為: for(i=getmy_0();i<=count-getmy_1();i++)

抑或是:

指針 p++;可以改為: p=p+getmy_1();


或者:給函數(shù)傳遞變量時,傳遞方在 變量上+F1(ID), 被調(diào)用的函數(shù)在 變量上--GET_IDX():

比如本來是
void f1(){
int i,j;
....
j=f2(i);
}

int f2(i){
return i*2;
}
修改為:
void f1(){
int i;
....
j=f2(i+F1(ID));
}

int f2(i){
return (i-GET_IDX())*2;
}


如程序被非法復(fù)制:從ID無法得到IDX,那么IDX和F1(ID)不相等,

那么getmy_0不再是0,getmy_1不再是1,


程序?qū)⒊霈F(xiàn)什么結(jié)果,誰都無法預(yù)料了。

---------------------------------------------------------
特點: 由于整個程序的加密,采用了“運算加密”的思路, 而非判斷加密, 又沒有用到任何一行 if判斷,讓解密者去想破腦袋吧。

即使猜測到有可能是這種加密思路,但是程序并不是基于if判斷跳轉(zhuǎn),加密的作用自然分布在程序的各個地方,怎么去改,也很傷腦筋了。
直接修改getmy_1和getmy_0,這個首先是得分析出加密思路時才能作出的。

另外修改getmy_1和getmy_0只是干掉簡單的部分。

還有一些是很難干掉的:

給函數(shù)傳遞變量時,傳遞方在 變量上+F1(ID), 被調(diào)用的函數(shù)在 變量上--GET_IDX():

比如本來是
void f1(){
int i,j;
....
j=f2(i);
}

int f2(i){
return i*2;
}
修改為:
void f1(){
int i;
....
j=f2(i+F1(ID));
}

int f2(i){
return (i-GET_IDX())*2;
}

另外,包括一些全局部變量的處理,可以在一些函數(shù)里面加上F1(ID);
在;另外一些地方進行-GET_IDX()的操作,并不會將代碼簡單集中放到一點的。

當(dāng)然,如果精準(zhǔn)的理解了整個程序的加密思路來說,這個也可以花時間干掉,不過這種加密方式本身目前是很少有人用的。

總之這種加密強度遠(yuǎn)高于簡單的if比較方式。這個是一個新的基本思路,我舉的例子只是一些簡單的例子,完全可以自己做得更加靈活。

本文引用地址:http://butianyuan.cn/article/201611/321562.htm

F1當(dāng)然是一樣的啊。只是ID不同。


順便回復(fù)上樓,我有個前提: 只要單片機具有真正唯一ID,這個意思包含: 單片的ID不可以復(fù)制。

你說那個地方只是怎么去拷貝程序出來, 如果單片機具有真正唯一ID, 拷貝程序是沒有用的。

大家先別拍磚頭,思路很不錯。從復(fù)雜度上已經(jīng)增加到了一定程度。
建議做成強制in-line,否則對破解人來說太明顯……因為大量的邏輯都指向某一個或某兩個函數(shù)……
別低估干這行的智商——所謂沒有金剛鉆,不攬瓷器活。另外,用減法做比較也是業(yè)內(nèi)常識……其它還有用異或結(jié)果是否為0……這些都是常見的特征……
對, inline!好思路, 必須的!

代碼尺寸就上去了哦~ 執(zhí)行效率也隨之受到影響……不過如果有內(nèi)部的什么1~4個周期的硬件CRC之類,就可以
解決效率問題,并且徹底把算法隱藏好……問題是……這個CRC硬件最好是不公開的才行……有一些芯片還有一些特殊矩陣轉(zhuǎn)置(permutation)外設(shè)——也都沒有對外公開……

隱藏加密算法的加密應(yīng)用范圍受到影響,因為用的人多了,自然就公開了,公開加密算法,沒有密鑰但依然很難解密的才有生命力,樓主這種思路是能夠增加破解的困難,不過只能給盜版者加工資。當(dāng)然有些小產(chǎn)品,利潤和市場本來不大,盜版的成本太高也的確能保護可憐的程序員

所有的單機程序都是可以破解的,真正要保護自己的成果其實并不是通過加密,而是通過網(wǎng)絡(luò)服務(wù),這就像殺毒軟件,只要聯(lián)上網(wǎng),主動權(quán)永遠(yuǎn)掌握在自己手中,這樣的軟件根本就永不著加密。就像微軟的WINXP,再怎么加密也會被破解,但是只要聯(lián)網(wǎng),就可以黑你屏,就像單機游戲,今天做出來,明天就被破解,可是網(wǎng)絡(luò)游戲,你見過破解的嗎?除非入侵服務(wù)器,只要一入侵就被發(fā)現(xiàn)。所以單片機要想完全保護產(chǎn)權(quán),就要提供網(wǎng)絡(luò)化服務(wù)。

首先不要忙著拍磚,我來整理一下思路。利用全球唯一ID(每顆MCU都有一個唯一ID)的加密精髓在于防止程序輕易讀出的情形,甚至HEX ROM根本無需加密,和破解讀出HEX code的難易程度沒有關(guān)系。實際上只需要兩步:
1.自己想一個認(rèn)為非常好的算法,利用MCU的GUID生成另外一個ID(可變長),再自己設(shè)計一個下載器(加密算法也在里邊)燒錄到EEPROM或Program ROM里邊。保管好燒錄器,不要外泄。你的燒錄器就是一個加密工具!
2.在你的程序當(dāng)中分布式的對用燒錄器燒進去的加密后ID解密。這個比較重要,因為解密代碼寫的過于集中便于反匯編分析。比如不要解密后不正確不要進入死循環(huán),不要立刻封殺所以功能,如果是盜版你故意給他幾個致命BUG,讓他抄襲后生產(chǎn)退貨,損失更大。加密的結(jié)果就是燒錄到每個MCU的HEXCODE是不相同的,即使讀出了一個MCU的HEXCODE,燒到另外的MCU是不能通過解密算法驗證的。唯一的解密的方法是去分析你得HEXCODE,分析出加密算法,破解者再設(shè)計出和你一樣的燒錄器!總之,這個方法只能對比較大的Program ROM有效果,如果是小的MCU,比如只有1KB ROM就很難做好,畢竟代碼少,容易分析。說實話,如果有這樣的功底的工程師去反匯編你的代碼,說不定他就正向設(shè)計來得更快!這只是防盜防火防小人而已。

用simlator去跟蹤程序。然后找到GUID。替換掉即可。

STM32的UID有一部分是說明這個片子在晶圓的XY坐標(biāo)位置的,一個晶圓上面所有的片子UID都不一樣,至于不同晶圓的UID如何實現(xiàn)不同我就不知道了。。在晶圓上實現(xiàn)個唯一ID又難了?激光幾閃,隨機割斷96個硅片的導(dǎo)線就獲得了96bit的唯一ID了------------------------

樓主這個加密方法確實不錯,不過前提是inline的方式,否則頻繁調(diào)用某個函數(shù)很快就會被發(fā)現(xiàn),另外加密后的IDX最好在啟動時就讀取到RAM中,否則頻繁讀取某個FLASH或EEPROM位置也很容易被發(fā)現(xiàn),最后,還需要選用解密成本較高的單片機,如最近一個朋友想解密一款NEC的單片機,讀出ROM的費用就需要近20萬。
另外樓上說這個方法簡單的,只是因為你已經(jīng)看到了樓主的加密思路,如果現(xiàn)在是先給個用這種方法加密的固件出來,我想就不會有人輕易下結(jié)論了。如果是inline函數(shù)并上去的話,那么有個小問題就是代碼量會超大。

樓主要研究軟件的加密算法,建議先去學(xué)習(xí)一下現(xiàn)在windows下一般應(yīng)用軟件加殼的各種原理,唯一ID在這個領(lǐng)域是完全不新鮮的一個東西,最常見的就是軟件根據(jù)CPU、硬盤或網(wǎng)卡的MAC來生成一個所謂硬件ID讓用戶注冊。
而算法加密更是五花八門,除了加密條件判斷外,還有代碼的動態(tài)解碼,就是用正確的KEY來解密函數(shù)A的代碼,再跳過去執(zhí)行,下次解碼函數(shù)B時又會覆蓋函數(shù)A的空間等等。
還有虛擬機加密,把一段x86代碼轉(zhuǎn)換為MIPS代碼,在虛擬機中運行,這樣如果破解不知道虛擬機模擬的是哪種匯編指令的話,反編譯就會很累,代價就是運行速度下降。

適合有很大rom的mcu 可以加入一些垃圾代碼。讀取硬件id或軟件id的這兩個點是爆破的主要地方。例如固件整體驗證的就是硬件id, 就算自己編寫編程器變換固件內(nèi)的其它key位置等, 整個算法驗證的還是當(dāng)前的mcu的硬件id是不是與這個固件匹配只要找到讀取這個id的地方補丁一下就完了。這個其實就類似與pc機上綁定機器的軟件的加密時一樣的。

你的方法必須保證你讀唯一ID的行為不被破解者看出。像STM32的獨立ID在某個固定地址,那么只要找出訪問那個地址的語句就可以了。

現(xiàn)在有不少量產(chǎn)編程器都支持根據(jù)唯一ID變換一些數(shù)據(jù)寫入指定地址,甚至支持自己編寫變換插件,每個單片機的程序都不一樣是完全可以做到的。

你算法設(shè)計的越復(fù)雜,如果不是用來直接保護你自己的利益,那么就是為他們謀福利了。

什么堅不可摧。專業(yè)的加密芯片都可以擺平。何況這玩意兒?



關(guān)鍵詞: 單片機唯一ID加

評論


技術(shù)專區(qū)

關(guān)閉