武装到链路层的加密通信方式

  cheney

    我把直接建立在物理层之上的一层协议叫做链路层。理论上不管你用的是什么通信协议和加密协议,在链路层看来都是0和1。根据物理层情况的不同,某些情形下链路层很容易直接暴露出来,比如说485通信方式。我只需要在485线路上搭上示波器就能情容易的观察到所有的数据。这种特性可能导致某些精心设计的加密协议毫无用武之地

    U1:可是我的数据都是加密的啊~你不能破解我的加密算法就不可能知道我的真实数据。

    H:在不知道加密算法的情况下,链路层读到的数据不能反转为真实数据,但也不代表完全没有用处。我完全可以记录下链路层的数据,用相同的数据来欺骗通信的双方。比如说,主机给终端发送一条命令(闪灯),终端接收后执行特定的动作(闪灯)。虽然这条命令可以被加密成无法识别的东西,但是我只需要将对应的链路层的数据帧记录下来,再次发给终端,终端就会产生误动作(再次闪灯)。

    U1 : 我可以在协议帧中增加随机数,即使相同的命令加密后也将是不同的。然后还可以增加时间相关性:比如在协议帧中说明该命令的适用时间,超过时间范围直接丢弃,不破解加密算法是不可能修改其中时间的;或者直接用时间相关信息作为密码来加密数据,超时的数据将无法被正确解析,也不会有误动作。

    H:以时间为基准的系统存在一个问题,如何进行时间同步。比如说终端被重启或者时间错误,主机首先需要同步从机的时间。如果我把从主机同步时间到发送命令整个都记录下来,还是照着原样数据发送,就实现了终端时间被不停的拉回原始点,伪造的命令也将被执行,依然会产生误动作。

    U2:这种情况可以使用滚动码方式通信。所谓滚动码就是:终端维护一个计数值 NumC,主机对每个终端也维护一个计数值NumH,存放在非易失空间。每次主机发送命令,都将NumH自加一后包含在协议帧。从机只接受主机计数值比自己计数值大的命令,同时让NumC = NumH。计数值只能朝着一个方向走,这样所有以前用过的帧都将不能用了。

    H:这种方式下破解的一个机会就是计数值溢出,假如说计数值是16位的,1秒通信一次,那么18个小时后,计数值就会回归起点,我就可以用18个小时前抓捕的帧来误导终端了。可是如果计数值的位数很大,虽然知道一定会有溢出的一天,但是如果那个时间是在几个世纪之后,那也完全没有意义了。另外还有一个方法就是改变终端的计数值,改变外挂的存放计数值的FLASH等,如果使用芯片内部的空间,那就更难破解了。

    U3:这种情况也可以通过挑战码的方式通信。这种方式需要主机和终端多次交互,如果主机要发送命令,过程应该是:

    1. 主机->终端: 发送命令帧+随机数

    2. 终端->主机: 发送应答帧+随机数R+对R加密后的数据f(R

    3. 主机->终端: 发送应答帧+f(R)

    整个过程只需要从R 到 f(R) 的变换过程是双方事先私下约定好的,就可以实现完全的加密,并且不用担心数据伪造。

    H:加上严格的时序相关性,几乎无法破解。