只要單片機(jī)具有真正唯一ID,就可以讓加密堅(jiān)不可摧
ID-->F1(ID) -----》IDX,
將ID通過(guò)自定義的一個(gè)算法F1,轉(zhuǎn)換為一個(gè)整數(shù)IDX , F1為不可逆運(yùn)算,也不能被輕易分析,這個(gè)實(shí)際上是容易實(shí)現(xiàn)的。
然后,將IDX保存到EEPROM或FLASH的任何地方,我們通過(guò)編一個(gè)函數(shù) GET_IDX()能夠讀出這個(gè)數(shù)即可。
第二環(huán):
再編一個(gè)函數(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()) 來(lái)替代0; 直接用(F1(ID)-GET_IDX()+1)來(lái)替代1;
第三環(huán):
在程序任何需要使用到1的地方,都可以考慮使用getmy_1()代替。
或即使本不使用1,也可以來(lái)用上一下:
如: 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ù)傳遞變量時(shí),傳遞方在 變量上+F1(ID), 被調(diào)用的函數(shù)在 變量上--GET_IDX():
比如本來(lái)是
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無(wú)法得到IDX,那么IDX和F1(ID)不相等,
那么getmy_0不再是0,getmy_1不再是1,
程序?qū)⒊霈F(xiàn)什么結(jié)果,誰(shuí)都無(wú)法預(yù)料了。
---------------------------------------------------------
特點(diǎn): 由于整個(gè)程序的加密,采用了“運(yùn)算加密”的思路, 而非判斷加密, 又沒(méi)有用到任何一行 if判斷,讓解密者去想破腦袋吧。
即使猜測(cè)到有可能是這種加密思路,但是程序并不是基于if判斷跳轉(zhuǎn),加密的作用自然分布在程序的各個(gè)地方,怎么去改,也很傷腦筋了。
直接修改getmy_1和getmy_0,這個(gè)首先是得分析出加密思路時(shí)才能作出的。
另外修改getmy_1和getmy_0只是干掉簡(jiǎn)單的部分。
還有一些是很難干掉的:
給函數(shù)傳遞變量時(shí),傳遞方在 變量上+F1(ID), 被調(diào)用的函數(shù)在 變量上--GET_IDX():
比如本來(lái)是
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);
在;另外一些地方進(jìn)行-GET_IDX()的操作,并不會(huì)將代碼簡(jiǎn)單集中放到一點(diǎn)的。
當(dāng)然,如果精準(zhǔn)的理解了整個(gè)程序的加密思路來(lái)說(shuō),這個(gè)也可以花時(shí)間干掉,不過(guò)這種加密方式本身目前是很少有人用的。
總之這種加密強(qiáng)度遠(yuǎn)高于簡(jiǎn)單的if比較方式。這個(gè)是一個(gè)新的基本思路,我舉的例子只是一些簡(jiǎn)單的例子,完全可以自己做得更加靈活。
F1當(dāng)然是一樣的啊。只是ID不同。
順便回復(fù)上樓,我有個(gè)前提: 只要單片機(jī)具有真正唯一ID,這個(gè)意思包含: 單片的ID不可以復(fù)制。
你說(shuō)那個(gè)地方只是怎么去拷貝程序出來(lái), 如果單片機(jī)具有真正唯一ID, 拷貝程序是沒(méi)有用的。
大家先別拍磚頭,思路很不錯(cuò)。從復(fù)雜度上已經(jīng)增加到了一定程度。
建議做成強(qiáng)制in-line,否則對(duì)破解人來(lái)說(shuō)太明顯……因?yàn)榇罅康倪壿嫸贾赶蚰骋粋€(gè)或某兩個(gè)函數(shù)……
別低估干這行的智商——所謂沒(méi)有金剛鉆,不攬瓷器活。另外,用減法做比較也是業(yè)內(nèi)常識(shí)……其它還有用異或結(jié)果是否為0……這些都是常見(jiàn)的特征……
對(duì), inline!好思路, 必須的!
代碼尺寸就上去了哦~ 執(zhí)行效率也隨之受到影響……不過(guò)如果有內(nèi)部的什么1~4個(gè)周期的硬件CRC之類,就可以
解決效率問(wèn)題,并且徹底把算法隱藏好……問(wèn)題是……這個(gè)CRC硬件最好是不公開(kāi)的才行……有一些芯片還有一些特殊矩陣轉(zhuǎn)置(permutation)外設(shè)——也都沒(méi)有對(duì)外公開(kāi)……
隱藏加密算法的加密應(yīng)用范圍受到影響,因?yàn)橛玫娜硕嗔耍匀痪凸_(kāi)了,公開(kāi)加密算法,沒(méi)有密鑰但依然很難解密的才有生命力,樓主這種思路是能夠增加破解的困難,不過(guò)只能給盜版者加工資。當(dāng)然有些小產(chǎn)品,利潤(rùn)和市場(chǎng)本來(lái)不大,盜版的成本太高也的確能保護(hù)可憐的程序員
所有的單機(jī)程序都是可以破解的,真正要保護(hù)自己的成果其實(shí)并不是通過(guò)加密,而是通過(guò)網(wǎng)絡(luò)服務(wù),這就像殺毒軟件,只要聯(lián)上網(wǎng),主動(dòng)權(quán)永遠(yuǎn)掌握在自己手中,這樣的軟件根本就永不著加密。就像微軟的WINXP,再怎么加密也會(huì)被破解,但是只要聯(lián)網(wǎng),就可以黑你屏,就像單機(jī)游戲,今天做出來(lái),明天就被破解,可是網(wǎng)絡(luò)游戲,你見(jiàn)過(guò)破解的嗎?除非入侵服務(wù)器,只要一入侵就被發(fā)現(xiàn)。所以單片機(jī)要想完全保護(hù)產(chǎn)權(quán),就要提供網(wǎng)絡(luò)化服務(wù)。
首先不要忙著拍磚,我來(lái)整理一下思路。利用全球唯一ID(每顆MCU都有一個(gè)唯一ID)的加密精髓在于防止程序輕易讀出的情形,甚至HEX ROM根本無(wú)需加密,和破解讀出HEX code的難易程度沒(méi)有關(guān)系。實(shí)際上只需要兩步:
1.自己想一個(gè)認(rèn)為非常好的算法,利用MCU的GUID生成另外一個(gè)ID(可變長(zhǎng)),再自己設(shè)計(jì)一個(gè)下載器(加密算法也在里邊)燒錄到EEPROM或Program ROM里邊。保管好燒錄器,不要外泄。你的燒錄器就是一個(gè)加密工具!
2.在你的程序當(dāng)中分布式的對(duì)用燒錄器燒進(jìn)去的加密后ID解密。這個(gè)比較重要,因?yàn)榻饷艽a寫(xiě)的過(guò)于集中便于反匯編分析。比如不要解密后不正確不要進(jìn)入死循環(huán),不要立刻封殺所以功能,如果是盜版你故意給他幾個(gè)致命BUG,讓他抄襲后生產(chǎn)退貨,損失更大。加密的結(jié)果就是燒錄到每個(gè)MCU的HEXCODE是不相同的,即使讀出了一個(gè)MCU的HEXCODE,燒到另外的MCU是不能通過(guò)解密算法驗(yàn)證的。唯一的解密的方法是去分析你得HEXCODE,分析出加密算法,破解者再設(shè)計(jì)出和你一樣的燒錄器!總之,這個(gè)方法只能對(duì)比較大的Program ROM有效果,如果是小的MCU,比如只有1KB ROM就很難做好,畢竟代碼少,容易分析。說(shuō)實(shí)話,如果有這樣的功底的工程師去反匯編你的代碼,說(shuō)不定他就正向設(shè)計(jì)來(lái)得更快!這只是防盜防火防小人而已。
用simlator去跟蹤程序。然后找到GUID。替換掉即可。
STM32的UID有一部分是說(shuō)明這個(gè)片子在晶圓的XY坐標(biāo)位置的,一個(gè)晶圓上面所有的片子UID都不一樣,至于不同晶圓的UID如何實(shí)現(xiàn)不同我就不知道了。。在晶圓上實(shí)現(xiàn)個(gè)唯一ID又難了?激光幾閃,隨機(jī)割斷96個(gè)硅片的導(dǎo)線就獲得了96bit的唯一ID了------------------------
樓主這個(gè)加密方法確實(shí)不錯(cuò),不過(guò)前提是inline的方式,否則頻繁調(diào)用某個(gè)函數(shù)很快就會(huì)被發(fā)現(xiàn),另外加密后的IDX最好在啟動(dòng)時(shí)就讀取到RAM中,否則頻繁讀取某個(gè)FLASH或EEPROM位置也很容易被發(fā)現(xiàn),最后,還需要選用解密成本較高的單片機(jī),如最近一個(gè)朋友想解密一款NEC的單片機(jī),讀出ROM的費(fèi)用就需要近20萬(wàn)。
另外樓上說(shuō)這個(gè)方法簡(jiǎn)單的,只是因?yàn)槟阋呀?jīng)看到了樓主的加密思路,如果現(xiàn)在是先給個(gè)用這種方法加密的固件出來(lái),我想就不會(huì)有人輕易下結(jié)論了。如果是inline函數(shù)并上去的話,那么有個(gè)小問(wèn)題就是代碼量會(huì)超大。
樓主要研究軟件的加密算法,建議先去學(xué)習(xí)一下現(xiàn)在windows下一般應(yīng)用軟件加殼的各種原理,唯一ID在這個(gè)領(lǐng)域是完全不新鮮的一個(gè)東西,最常見(jiàn)的就是軟件根據(jù)CPU、硬盤(pán)或網(wǎng)卡的MAC來(lái)生成一個(gè)所謂硬件ID讓用戶注冊(cè)。
而算法加密更是五花八門(mén),除了加密條件判斷外,還有代碼的動(dòng)態(tài)解碼,就是用正確的KEY來(lái)解密函數(shù)A的代碼,再跳過(guò)去執(zhí)行,下次解碼函數(shù)B時(shí)又會(huì)覆蓋函數(shù)A的空間等等。
還有虛擬機(jī)加密,把一段x86代碼轉(zhuǎn)換為MIPS代碼,在虛擬機(jī)中運(yùn)行,這樣如果破解不知道虛擬機(jī)模擬的是哪種匯編指令的話,反編譯就會(huì)很累,代價(jià)就是運(yùn)行速度下降。
適合有很大rom的mcu 可以加入一些垃圾代碼。讀取硬件id或軟件id的這兩個(gè)點(diǎn)是爆破的主要地方。例如固件整體驗(yàn)證的就是硬件id, 就算自己編寫(xiě)編程器變換固件內(nèi)的其它key位置等, 整個(gè)算法驗(yàn)證的還是當(dāng)前的mcu的硬件id是不是與這個(gè)固件匹配只要找到讀取這個(gè)id的地方補(bǔ)丁一下就完了。這個(gè)其實(shí)就類似與pc機(jī)上綁定機(jī)器的軟件的加密時(shí)一樣的。
你的方法必須保證你讀唯一ID的行為不被破解者看出。像STM32的獨(dú)立ID在某個(gè)固定地址,那么只要找出訪問(wèn)那個(gè)地址的語(yǔ)句就可以了。
現(xiàn)在有不少量產(chǎn)編程器都支持根據(jù)唯一ID變換一些數(shù)據(jù)寫(xiě)入指定地址,甚至支持自己編寫(xiě)變換插件,每個(gè)單片機(jī)的程序都不一樣是完全可以做到的。
你算法設(shè)計(jì)的越復(fù)雜,如果不是用來(lái)直接保護(hù)你自己的利益,那么就是為他們謀福利了。
什么堅(jiān)不可摧。專業(yè)的加密芯片都可以擺平。何況這玩意兒?
評(píng)論