Encryption 为什么不同的AES实现会产生不同的输出?

Encryption 为什么不同的AES实现会产生不同的输出?,encryption,cryptography,aes,Encryption,Cryptography,Aes,我觉得我对散列函数和它们所包含的契约有很好的理解 输入X上的SHA1将始终产生相同的输出。您可以使用Python库、Java库或纸笔。这是一个函数,它是确定性的。我的SHA1和你的、爱丽丝的和鲍勃的做得一样 据我所知,AES也是一个函数。你输入一些值,它就会输出密文 那么,为什么会有人担心Truecrypt(例如)被“破坏”了呢?他们不是说AES坏了,他们是说实现它的程序可能坏了。理论上,AES是固态的。那么,为什么不能通过Truecrypt运行一个文件,通过“reference AES”函数运

我觉得我对散列函数和它们所包含的契约有很好的理解

输入X上的SHA1将始终产生相同的输出。您可以使用Python库、Java库或纸笔。这是一个函数,它是确定性的。我的SHA1和你的、爱丽丝的和鲍勃的做得一样

据我所知,AES也是一个函数。你输入一些值,它就会输出密文

那么,为什么会有人担心Truecrypt(例如)被“破坏”了呢?他们不是说AES坏了,他们是说实现它的程序可能坏了。理论上,AES是固态的。那么,为什么不能通过Truecrypt运行一个文件,通过“reference AES”函数运行它,并验证结果是否相同呢?我知道它绝对不是那样工作的,但我不知道为什么

AES在这方面与SHA1有什么不同?当Truecrypt AES和Schneier*AES都有相同的输入时,为什么Truecrypt AES会输出一个与Schneier*AES不同的文件

最后,我的问题归结为:

My_SHA1(X)=Bobs_SHA1(X)=等

但是TrueCrypt_AES(X)!=超晶AES(X)!=VeraCrypt_AES(X)等。为什么?所有这些程序都包装了AES,但有不同的方法来确定诸如初始化向量之类的东西吗


*这就是我的文件加密程序的名称,如果我在您给出的SHA-1示例中编写了一个,那么函数只有一个输入,并且任何正确的SHA-1实现在提供相同的输入数据时都应该产生与任何其他实现相同的输出

然而,对于AES来说,事情有点棘手,因为您没有明确说明“AES”的确切含义,这本身似乎是实现之间感知差异的根源

首先,“AES”不是一个单一的算法,而是一系列采用不同密钥大小(128、192或256位)的算法。AES也是一种分组密码,它接受一个128位/16字节的明文输入块,并使用密钥对其进行加密以生成一个16字节的输出块

当然,在实践中,我们经常希望一次加密超过16字节的数据,因此我们必须找到一种方法来重复应用AES算法,以便加密所有数据。天真地说,我们可以将它分成16字节的块,然后依次加密每个块,但这种模式(称为电子码本或ECB)被证明是可行的。相反,通常使用各种其他更安全的,其中大多数需要初始化向量(IV),这有助于确保使用相同密钥加密相同数据不会产生相同的密文(否则会泄漏信息)

这些模式中的大多数仍然在固定大小的数据块上运行,但我们通常希望加密不是块大小倍数的数据,因此我们必须使用某种形式的,并且对于如何将消息填充到块大小倍数的长度,存在各种不同的可能性

因此,为了将所有这些放在一起,“AES”的两个不同实现应该产生相同的输出,如果以下所有内容都相同:

  • 纯文本输入数据
  • 键(因此键大小)
  • 四,
  • 模式(包括任何特定于模式的输入)
  • 填充物

铱涵盖了TrueCrypt和其他使用名义上相同(AES)算法的程序之间输出不同的许多原因。如果您只是检查实际的初始化向量,那么这些向量往往是使用ECB来完成的。这是使用ECB的唯一好时机——确保算法本身得到正确实现。这是因为欧洲央行虽然不安全,但在没有静脉注射的情况下也能工作,因此更容易进行“苹果对苹果”的检查,尽管铱星指出还有其他障碍

对于测试向量,键与纯文本一起指定。测试向量被指定为块大小的精确倍数。或者更具体地说,对于纯文本,它们的大小往往正好是1个块。这样做是为了从可能的差异列表中删除填充和模式。因此,如果在两个AES加密程序之间使用标准测试向量,就可以消除纯文本数据差异、密钥差异、IV、模式和填充的问题

但请注意,您仍然可以有差异。AES与哈希一样具有确定性,因此每次使用AES都可以得到与使用哈希相同的结果。只是需要控制更多的变量才能得到相同的输出结果。Iridium并没有提到的一个问题是输入(键和纯文本)的持久性。我在对照TrueCrypt检查Serpent的参考实现时遇到了这个问题。只有当我将键和纯文本颠倒过来时,它们才会向文本向量提供相同的输出

要详细说明这一点,如果您的纯文本全部16个字节都是0,并且密钥是31个字节的0和一个字节的“33”(在256位版本中),如果参考实现的“33”字节位于字节字符串的左端,您必须先输入TrueCrypt 31'00'字节,然后再输入右侧的'33'字节,才能获得相同的输出。正如我提到的,一个持久性问题

至于TrueCrypt,即使AES仍然安全,也可能不安全,这是绝对正确的。我不知道TrueCrypt所谓的弱点的具体情况,但让我来介绍一下一个程序可以正确地关闭AES,但仍然不安全的几种方法

一种方法是,在用户输入密码后,程序以不安全的方式为会话存储密码。如果它没有在内存中加密,或者它使用自己的内部密钥加密您的密钥,但无法很好地保护该密钥,您可以让Windows将其写在硬盘驱动器的普通版上,以便所有人都可以读取它