我想在C ++中使用CBC MAC。首先,我希望找到一些块密码的实现,我将在CBC模式下使用,我理解的是CBC MAC。但我有两个问题:
1)如果要验证的消息长度不是分组密码块长度的倍数,我该怎么办?
2)为了加强CBC MAC,Wiki上提到的一种推荐方式是将消息的长度放在第一个块中。但是我应该如何编码长度,如字符串?还是二进制?如果密码的块长度为64位,那么我将数字编码为64位数吗?例如如果消息长度为230,我应该使用以下值作为第一个块:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 11100110
答案 0 :(得分:1)
这取决于第二个问题。你必须"垫"带有东西的消息,直到它是块大小的倍数。在计算MAC之前将填充字节添加到消息中,但仅传输/存储原始消息/等。
对于MAC,最简单的方法是用零填充。但是这有一个漏洞 - 如果消息部分以一个或多个零结尾,攻击者可以添加或删除零而不更改MAC。但是如果你做了第2步,那么这次和另一次攻击都会得到缓解。
如果您在消息前添加消息的长度(例如,不仅仅是在第一个块中,而是第一个块中的第一个),它会减少有时添加的能力/删除零。它还减轻了攻击者伪造消息的能力,其中添加了整个任意额外块。所以这是一件好事。出于完全实际的原因,它也是一个好主意 - 你知道消息有多少字节而不依赖于任何外部手段。
长度的格式是什么并不重要 - 某些编码的ASCII版本或二进制文件。然而,实际上它应该总是简单的二进制。
没有理由长度中的位数必须与密码块大小匹配。长度字段的大小必须足够大以表示消息大小。例如,如果消息大小的长度范围为0到1000个字节,则可以添加无符号的16位整数。
首先在发送方和接收方计算MAC之前完成此操作。本质上,长度与消息的其余部分同时进行验证,从而消除了攻击者伪造更长或更短消息的能力。
有许多像AES这样的分组密码的开源C实现很容易找到并且能够正常工作。
<强>买者强> 据推测,问题的目的只是为了学习。任何严肃的使用应该考虑更强大的MAC,如其他评论和良好的加密库建议。还有其他弱点和攻击可能非常微妙,因此您永远不应该尝试实现自己的加密。我们都不是加密专家,这只应该用于学习。
顺便说一句,我推荐Bruce Schneier的以下两本书: