为什么未经身份验证的加密不安全?

2020-09-21 02:50:46

密码学是一门复杂的学科。如果您不知道自己在做什么,可以介绍许多微妙的问题。

有一句常见的口头禅:“不要自编密码”。这是因为经验不足和经验丰富的开发人员经常构建不安全的加密系统。

然而,必须要有一条线--它什么时候开始变得“自己滚”?特别是在嵌入式系统中,有时需要使用自定义协议,开发人员会陷入密码学的危险领域。

我们看到的最常见的错误之一是使用未经验证的加密。

加密是使用密钥将明文编码成密文,目的是保证明文的机密性。

只有拥有正确密钥的人才能解密密文并将其转换回明文。

攻击者可以修改密文并导致明文更改。加密中没有固有的方法来检测此更改。

加密不提供真实性。您无法检查邮件是否真实且未被篡改。

许多加密算法只对固定大小的数据块进行操作-它们被称为块密码。为了加密更长长度的数据,使用操作模式来重复应用块密码。

一种操作模式称为CBC(密码块链接)。在加密数据时,使用称为“异或”的操作将先前的密文块混合到当前的明文块中。这在图表中用圆圈中的+表示。

还有一个称为初始化向量或IV的输入。这是算法的随机输入,目的是确保密文不同,即使加密的是相同的明文。这可以防止有关内容的信息泄露。

解密是相似的。将前一密文块与块密码的输出进行异或运算,以获得明文。

异或是一种确定性运算。如果我们看一下单个比特,那么它的工作方式如下:

我总是认为这是“如果一个输入是高的,反转另一个输入,否则就别管它了”。

A:0 1 0 1 1 0 0 1(0x59)B:1 1 1 0 0 0(0xF0)O:1 0 1 0 1 0 0 1(0xA9)。

这意味着将其中一个输入修改为异或会导致可预测的输出更改。并且操作可以很容易地逆转。

让我们回顾一下CBC是如何在解密中使用这一点的。在第一个块中,IV与块密码的输出进行异或运算。IV与密文一起传输,攻击者可以随意修改两者。

我们可以使用密钥和所有0x00的初始化向量(在CyberChef上)来加密字符串“A dog‘s早餐”。

如果我只更改密文中的一个字节,整个消息就会被破坏(在Cyberchef上)。我无法通过更改密文来可预测地修改此明文。

但是攻击者也可以控制IV。让我们将IV的第一个字节设置为0xFF(在CyberChef上)。只有明文的第一个字节改变了!

而且它已经在可预见的范围内发生了变化。大写A(ASCII 0x41)与0xFF进行了独占运算,变成了0xBE(虽然它高于正常的ASCII范围,但解码为3)。

A:0 1 0 0 0 1(0x41)B:1 1 1(0xFF)O:1 0 1 1 1 0(0xBE)。

这是一个非常高级别的控制!攻击者现在可以在不被检测到的情况下修改明文。让我们试着显著改变一下它的意思。

最初的信息包含“狗的早餐”。我们能把这个狗宴改成猫宴吗?

我们将原始明文与所需明文进行异或运算(在CyberChef上)。请注意,输出中只有我们更改的字符的值。

将输出作为IV放入解密,我们已经成功地更改了消息(在CyberChef上)。所有这一切都是在不知道钥匙的情况下发生的。

当然,攻击者需要了解明文才能利用此攻击。然而,部分或全部信息被知道是非常常见的。例如,当我们访问大多数网站时,响应的第一部分将是“HTTP/1.1200OK”。如果这只受CBC加密保护,我们可以将其更改为“HTTP/1.1404No”,从而更改浏览器的行为(在CyberChef上)。

这也不仅仅影响第一个数据块。在第一个块之后,在异或操作中使用前一个密文块,而不是IV。攻击者可以修改密文并最终控制明文。

不过,这是要付出代价的--之前的明文块将因此完全损坏。

我们把“波特”改成“猫”吧。我们需要在密文中找到正确的位置。AES(我们使用的加密算法)在16字节块中工作。单词“baud”是85个字符,所以在第6个区块中。因此,我们希望修改第5块密文。

异或运算比上一次稍微复杂一些-我们现在需要对密文、原始文本和所需文本(在CyberChef上)进行异或运算。但是更改这4个字节,我们就将单词“baud”更改为“cat”。

唯一的问题是,正如预期的那样,前一个块已完全损坏。虽然在这种情况下,它使消息的一部分变得毫无意义,但在实施攻击时往往没有任何影响。

上述问题使得攻击者能够在未被检测到的情况下修改明文。这在某些情况下会是一个问题,例如门的锁定/解锁消息。

但是不对您的加密进行身份验证可能会导致更严重的问题。一种称为填充Oracle攻击的攻击类型可让攻击者通过发送大量巧尽心思构建的数据包来获取加密密钥。

分组密码只在固定的块上操作。如果数据比块短,则必须对其进行填充。有许多方法可以做到这一点,例如附加填充字节的数量(例如0x02 0x02或0x05 0x05 0x05)。解密过程可以检查该填充是否正确,并且在每种情况下响应不同。

攻击者可以利用这些差异响应来泄露密钥。这可能会破坏消息的机密性和完整性。

添加消息验证码(MAC)。这是提供真实性和完整性的密钥加密校验和。

即使有了这个建议,也有很多陷阱。以错误的顺序应用身份验证和加密可能会导致弱点;这种情况非常常见,因此被认为是加密末日原则。

通常,开发人员不应该在这一级别使用密码学,除非他们具有适当的技能。这说起来容易,但要付诸行动就更难了。使用默认安全的加密库和API有一个很大的趋势,它们为开发人员提供有用的功能,而不给他们太多的绳索,以至于他们可能会上吊。