遥控车钥匙算法之KeeLoq

背景

在整车安全方案制定的过程中,一般不会涉及到遥控车钥匙安全方案的设计,因为其中的协议和加解密算法已经非常成熟。但遥控车钥匙的攻防一直是行业内的高光领域,是车联网安全工程师理解车联网安全的重要起点之一。当我们理解了遥控车钥匙的攻击方式之后,我们才能够充分理解包含在遥控车钥匙之中的通信协议和加密算法的设计意图(实际上本人为了深入理解遥控车钥匙的通信协议,完整实现了整个攻击过程,并深入分析了协议内容,详见本人发表在看雪论坛上的相关文章《解锁一辆车的非“优雅”方式》)。从这个经典的模块出发,我们可以将相关的思路带入到ECU之间的安全通信,即SecOC的方案设计之中,也可以将其设计理念融入数字车钥匙的安全方案。

除了通信协议,遥控车钥匙的另一个安全重点是遥控车钥匙的加密算法,其中包含了两个经典的加密算法:keeloq和hitag。可能有人会问,加解密算法,无论是对称的还是非对称的,都有那么多经典的可选,为什么在遥控车钥匙的设计中搞出了两个闻所未闻的新算法,我觉得其中的重要原因是遥控车钥匙的算力和耗电。从美观和实用的角度出发,遥控车钥匙的体积一般较小,这也就意味着遥控车钥匙不会容纳大容量的电源,一般为一颗纽扣钥匙,并且一颗纽扣钥匙一般需要工作2年以上,因此整个PCB板的耗电量也严格受控,因此处理器芯片不可过于复杂,不能执行太复杂的计算。基于如上原因(我认为),遥控车要是领域的专用加解密算法应运而生。其中,keeloq 就是 mirochip 设计和拥有的专有分组密码算法,在RKE(Remote Keyless Entry)中广泛使用。

符号

在正式介绍Keeloq的算法原理之前,我们先了解下文中使用到的相关函数的定义:

算法

Keeloq为分组加密算法,分组密码的密钥长度为64位,分组长度为32位。算法使用两个寄存器运行:

一个64位的密钥寄存器,用来存储密钥;

一个32位的文本非线性反馈移位寄存器(NLFSR),用来存储运算过程中的文本。

密钥寄存器 

密钥寄存器以简单的循环移位的方式运行,初始状态使用64位加密密钥填充。寄存器第i轮状态表示为:

在每一轮中,寄存器内容简单旋转,然后取最低位进行运算(表示r位的循环右移):

变量x循环右移n位之后取最低位的算法实现如下:

def bit_of(x, n):

    x = (((x)>>(n))&1)

    return x

文本寄存器

32位文本寄存器以非线性反馈寄存器的形式运行,第i轮的状态表示为:

如下流程图简单描述了整个keeloq加密过程的实现原理:

Keeloq加密算法

寄存器初始值由明文表示:

  

密文为文本寄存器进行528轮计算之后的结果:

 

在每一轮中,31个最高有效位(MSB)向右移一位,变成下一轮中的31个最低有效位;新一轮的MSB的生成,是由文本寄存器和密钥寄存器中一些比特位的非线性组合:

每一轮的计算过程实现如下,其中i代表轮数,index_tables表示NLF查找表系数,x依然代表明文消息:

(x>>1) ^ ((bit_of(x,0) ^ bit_of(x,16) ^ bit_of(key,i&63) ^ bit_of(0x3A5C742E, index_table(x,1,9,20,26,31)))<<31)

由于NFL函数接收的输入只有32种可能,所以通常通过查找表的方式定义。如果输入为5个比特位,那么就等于十六进制数LSB。或者,可能以代数的形式[2, 5, 9]写入NLF:

NLF查找表的实现(其中x代表明文消息):

def index_table(x, a, b, c, d, e):

    y = (bit_of(x,a) + bit_of(x,b)*2 + bit_of(x,c)*4 + bit_of(x,d)*8 + bit_of(x,e)*16)

    return y

加密过程

在指定的一轮计算中,对除了LSB以外的比特位进行的操作仅仅是移位:

在每一轮的计算过程中,没有必要保持对整个文本寄存器状态的跟踪,仅仅保持对每一轮中新生成的比特位的跟踪,即MSB,即可完整记录下一轮运算后的结果。经528轮计算中的每一轮计算后产生的文本寄存器的32位初始值及MSB被定义为比特流​​​​​​​,这个比特流被称为加密状态。 

加密状态的32位LSB是原始明文:

第i轮后文本寄存器的MSB是(31+i)比特位的加密状态。

如上流程看起来有点复杂,我们可以通过观察计算过程来简化加密流程,在第i+1轮中,只有第​​​​​​​比特位需要计算(根据比特位​​​​​​​和密钥中的比特位​​​​​​​)。在第i轮中,比特位​​​​​​​将与文本寄存器中的内容完全相同。描述为:

在528轮计算之后,从加密状态的32位MSB中取得密文:

由于非常简单的密钥时间表,一个完整的KeeLoq加密仅仅采用64轮加密​​​​​​​次,使用同一个密钥k:

 

综上,加密函数实现如下:

def keeloq_encrypt(msg, key):

    x = msg

    for i in range(528):

        x = (x>>1) ^ ((bit_of(x,0) ^ bit_of(x,16) ^ bit_of(key,i&63) ^ bit_of(KeeLoq_NLF,index_table(x,1,9,20,26,31)))<<31);

    return x

总结

Keeloq的运算主要为异或和移位,因为这两种操作使用硬件电路可以简单高效地实现。我们可以简单地将Keeloq的算法抽象为一句话,作为本文的结尾:明文与密钥基于移位、查找表和异或的运算。

参考

[1] http://ww1.microchip.com/downloads/en/devicedoc/40209c.pdf

[2] https://en.wikipedia.org/wiki/KeeLoq

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

车联网安全杂货铺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值