目前市面上很多防抄板加密方案都是基于加密芯片的安全存储和密文通讯来实现对主MCU方案的保护。比如把主MCU用到的一些参数、配置信息等存储在加密芯片里面,然后通过芯片的ID、随机数R等因子使用加密秘钥Key计算临时过程秘钥Key’,再使用临时过程秘钥Key’对数据做加解密和密文通讯,这样来做到每一颗芯片、每一次通讯的加密数据都是不一样,防止数据在通讯线路上被破解。
如上图,主MCU函数FUNC调用是的一些关键参数或数据Data没有存储在主MCU中,而是存储在加密芯片里,主MCU要正确运行函数FUNC需要使用到加密芯片里的Data数据,这就需要先从加密芯片将Data数据读取到主MCU。程序员为了增加加密方案可靠度,设计成让主MCU的芯片序列号ID1、产生的随机数R1和加密芯片的芯片序列号ID2、产生的随机数R2参与计算临时过程秘钥,加密芯片使用秘钥Key对(ID1⊕RAND1⊕ID2⊕RAND2)这些因子运算得到临时过程秘钥Key’,再使用Key’对数据Data做加密得到密文数据Data’。主MCU在收到密文数据Data’和ID2和R2后,使用同样的方法计算得到临时过程秘钥Key’,在使用Key’对密文数据Data’解密得到明文数据Data。主MCU的FUNC调用Data后程序就能正常使用了。
上述加密方案貌似安全可靠,但实际上对于经验丰富的黑客来说破解难度不大。
首先我们分析该方案最重要的技术点就是加解密使用的临时秘钥的因子由主MCU芯片和加密芯片的双方的ID和随机数参与,使得每次通讯线路上的密文都是变化的。但是主MCU反汇编程序和ID1、R1、Data’、ID2、R2还是很容易得到的,那么只要我们想办法让主MCU密文读数据时固定发ID1和R1就行了,这时主MCU解密假加密芯片回的固定密文数据Data’是可以得到正确明文数据Data的。
实现上述破解方式的前提条件是主MCU的程序BIN或HEX码是通过破解可以得到的,目前主流大多数MCU都是可以破解的,有很多专业的公司或团体做这方面的服务。拿到破解得到的BIN或HEX码后,接下来我们分两步走来实现破解主MCU和加密芯片的联动的整体加密方案,分别是固定主MCU的ID1和随机数R1。下面以STM32来模拟解析整个破解过程。
芯片的唯一ID一般都是存储在一个固定地址上连续存放的,知道芯片型号后这个ID1的存放地址很容易得到,我们在HEX码中很容易得到这个地址。比如STM32的UID地址在0x1FFFF7E8(小端模式),这时我们在HEX码中搜索E8F7FF1F(大端模式),如果找不到,可能是因为编译优化了,可以尝试搜索高3字节F7FF1F或其中几个字节,很容易就找到这个关键字,这时你只需要把HEX码这个位置的UID地址值改成你的设定的Flash地址值0x00005000,再在这个地址上写上你的ID(比如1122334455667788)就能实现你想要的ID1值了。如下图:
固定随机数相对于ID有些难度,如果有随机数发生器,那么把随机数发生器产生随机数值的地址改成你的固定地址,方法可以完全参照上面固定ID值得方法。如果没有随机数发生器,无非也是使用AC、DC等值作为因子,然后配合srand产生随机数,想办法在产生随机数前把这些因子固定,那么主MCU的随机数也可以做到的特定时间特定的代码处产生的随机数也是固定值。这个需要破解者有一定的反汇编能力,想办法找到这些作为随机数发生因子寄存器,用上述一样的方法把这些调用的地方改成你的固定的Flash地址,并在这个地址上写上你的目标值。如下产生随机数因子的样例:
我们只需要在HEX里找到ADC1.DR的地址,把他改到一个固定的FLASH地址就可以了。如果找不到ADC1.DR的地址,可以尝试去找ADC1的地址(0x40012400),把ADC1的地址改到一个固定地址(0x00005000),这样就可以把该处调用ADC1产生随机数因子的功能失效,这样每次程序运行时在该处调用ADC1产生的随机数因子是固定值,以达到固定每次产生随机数的值。
通过上述方式把STM32的ID1和随机数R1固定后,把新的HEX或BIN文件烧入到一颗新的STM32芯片,并把芯片贴装的装有原装加密芯片的目标板上,目标板工作后,在线路上监控通讯数据,得到ID1,R1,ID2,R2和密文数据Data’。
得到数据后,再开发一颗假加密芯片就可以了,假加密芯片收到的STM32发送固定的ID1和R1后只要回上述监控得到的固定的ID2,R2和密文数据Data’就可以了,STM32收到ID2,R2和Data’后就可以解密得到正确的Data。破解者使用固定ID1、随机数R1的HEX或BIN下载文件和自己制作的假加密芯片就可以批量生产破解的目标板了。如下图:
看了上述破解方式后是不是觉得这种貌似很安全的加密方案很容易就破解了?事实就是现在很多破解公司对主流MCU和加密芯片的破解能力都很强大,特别是针对主流MCU的反汇编和对逻辑加密芯片。特别是针对逻辑加密芯片,加密方式就是固定的几种方式,只要破解了一种方式,那么只要使用这种逻辑加密芯片和这种加密方式的产品都很容易破解,就像上述破解方式,破解者不需要去破解加密芯片,只需要通过固定ID和随机数的方式就能绕开加解密算法和秘钥。如果那使用了上述加密方法的,赶紧去检查下你的HEX或BIN下载码吧,看看是不是自己就能轻松破解自己的方案了。。。
那么有没有好的方法来保护产品呢,对于使用逻辑加密芯片的加密方案,开发者可以通过以下的一些小技巧来增加被破解的难度,比如:
**1、访问ID或随机数因子时,尽量不要使用常量直接访问目的地址,可以使用一个假地址再通过变量异或、加减或其他算法来得到目的地址,以防止破解者轻易找到这个地址来窜改。
2、秘钥值尽量不要连续存放在一个常量或变量数组里,尽量分开存放,使用前通过一些算法计算再组成正确的秘钥值。
3、主MCU程序做完整性校验,完整性校验绑定UID,防止主MCU程序被破解者破解得到后窜改来跟踪、分析、破解。上面讲的破解方法就是利用主MCU没有做程序完整性校验来固定ID和随机数从而轻易破解的,如果有完整性校验,破解难度就会增加。
4、设计加密方案时尽量不要使用判断正确就继续执行错误就报错这种简单的判断逻辑,可以设计成错误后继续执行,只是在后续执行过程中在不特定的地方出不特定的错误。
5、加密方案里使用的一些校验算法、加解密算法等,尽量不是用标准算法,可以使用这些算法的变异算法。**
通过上述方式,设计的加密方案被破解的难度会大大提高。但是现在有很多专业的破解团队,对主流芯片的反汇编能力超强,反汇编后还提供C代码服务供破解者二次开发,上述加密方式通过超强的反汇编能力,还是可以做到破解的,只是代价会大大提高。那有没有更加安全的加密方式呢?答案是有的,那就是采用可编程加密芯片!
可编程加密芯片可以理解成一种安全MCU,采用智能卡安全核,芯片本身安全可靠。可编程加密芯片除了拥有逻辑加密芯片的功能外还具有可编程功能。把主MCU的部分功能或算法放到可编程加密芯片里去运行,比如主MCU里有原来一个计算一个圆的面积的功能,这时我们把计算圆的面积的功能代码放到加密芯片里去,主MCU需要计算面积时,只需要把半径r传递给加密芯片,加密芯片收到半径r后自己运算圆的面积S=πr²,然后把面积S返回给主MCU就可以了。这种方案相当于整个加密方案是双MCU模式,即使主MCU被反汇编破解了,只要加密芯片安全可靠,破解者就无法得到计算圆面积的功能。
目前市场上逻辑加密芯片比较多,可编程加密芯片比较少,像中巨伟业的SMEC98SP、SMEC80ST,凌科信安的LKT4200、LKT4304,都属于可编程加密芯片。