细节很重要。
正如@Ricky 指出的那样,与不会截断 HMAC 值的类似情况相比,显示截断的 HMAC 值不会帮助攻击者找到密钥。这是有道理的:截断只删除信息。
但是,攻击者最终并没有获得密钥。攻击者真正想要的是伪造,即计算一些计算机将接受为自己的 HMAC 值。找出密钥可以进行伪造,但伪造的能力并不一定需要知道私钥。
幸运的是,HMAC 往往表现得像PRF,因此有两种已知的伪造方法:
对可能的密钥执行暴力枚举,直到找到正确的密钥(与几个已知值+HMAC 对匹配的密钥)。通过选择足够大的空间以使枚举不切实际(即,您生成具有加密强 PRNG 的 128 位密钥)的密钥来击败此攻击。
运气。攻击者发送一个随机的比特序列作为 HMAC 值,并希望它能够工作。通过不将 HMAC 值截断到太小的长度和/或应用其他缓解措施(例如只允许一次尝试和不可撤销地拒绝曾经显示甚至单个虚假 HMAC 值的设备(如您所做的那样))来击败此攻击。
“运气”攻击的概率为 2 - n,其中n是截断的 HMAC 输出的大小(以位为单位)。即,如果输出为 32 位,那么基于运气的伪造有 40 亿分之一左右的概率未被发现。总的来说,这是 32 位输出所能做到的最好的;HMAC 表现为 PRF 意味着它在这方面是“最佳的”。如果截断到 8 位,那么攻击成功的概率是 256 分之 1,这可能太不舒适了。但这是您根据使用情况做出的决定。
另外(再次正如@Ricky 指出的那样),请注意重放攻击。一个有效的 MAC,假设没有伪造,只向计算机证明它在某个时候看到并“批准”了消息内容——但不是它是它看到的最后一条消息。旧的消息-HMAC 对可以由假设备再次发送。要击败重放攻击,您必须在计算机上保持某种状态(计算机必须记住有关设备的某些信息,例如“消息序列号”,它是计算 MAC 的数据的一部分,并为每条消息递增) .