跨平台AES加密是如何工作的


How does cross platform AES encryption work?

我已经能够在php和objective-c代码中成功加密和解密AES-256。我不会在这里张贴任何代码,因为我已经尝试了许多品种和没有工作。我不知道这些加密功能是如何工作的…AES是一个标准化的算法,所以为什么它不能在我的想法归结为

a)静脉
B)一些编码错误

C)填充的差异(应该与解密无关)。

如果有人的AES函数在php和objective-c中都能工作,那就太好了,但如果没有,任何帮助理解导致这些不同结果的原因将是非常感激的。

如果你想要一个更窄的问题,它是关于这个AES密码的编码,iv和块大小。

1)在密钥和明文/密文方面使用什么编码是否重要?基本上我猜这不是纯文本的问题,因为我将使用的所有字符(至少在测试期间)都是标准的ASCII符号。但假设php字符串是ASCII,我在objective-c中使用UTF8。我不知道php是使用ASCII码还是ie字节。

2)据我所知,ECB模式不使用iv(如果错误则正确)。CBC模式使用iv,此时iv必须与密文一起记录。现在这个键在php中是16或32个字符长(取决于128和256块大小)。这意味着16还是32字节?字符串1234567890123456789012在ASCII和UTF8转换为字节时是相同的吗?

3)就算法而言,块大小和密钥大小有什么区别?基本上它们都是相同的算法,只是参数不同?使用256位密钥和128位密钥只是传递哪个密钥的问题

(另外,请注意,我一直使用base64编码在应用程序之间传输字符串以进行测试)

谢谢,Elijah

要使解密正常工作,所有必须完全相同。同样的调式,同样的IV,同样的调式。特别是键必须相同。字节对字节是一样的。一点一点都一样。AES被设计成即使有一个密钥不正确也不能正确解密。

看了你的问题,我怀疑你的问题出在钥匙上。真正的密钥不是字符,而是字节。有许多不同的方法可以在字符和字节之间进行转换,这可能导致解密失败。您需要确定这两个键匹配的是字节对字节,而不是字符对字符。至少,您需要明确使用什么映射。不要依赖系统默认值,因为不同系统的默认值可能不同。

看看你的三个问题:

1)对于明文编码,您将得到输入的内容:UTF-8 in, UTF-8 out。如果你想转换成不同的编码,那么你必须在解密后进行。

2)你是对的,ECB不需要IV,但ECB模式会泄露信息,应该避免。请使用CBC或CTR方式,两端使用相同的方式。IV与块大小有关,因此对于AES IV总是16字节或128位。您不能保证ASCII和UTF-8是相同的。UTF开头可能有一个BOM。ASCII可能在末尾有一个c风格的零字节。不要用字符来考虑,要用字节来考虑。所有内容都必须在字节级别上匹配。在CBC模式下,故障IV将修改第一个块,但解密后续块OK。

3) AES的块大小固定为128位,不能更改。密钥大小的限制较少,可以是128位、192位或256位。实际上,大多数人似乎使用128或256位。块是一种方便大小的处理单元,它在非常低的级别内置于密码中。键决定了在处理过程中对块做了什么。这样键就更灵活了。你输入的键是用来构建一些内部结构的,也就是"圆键"。这个过程被称为"键扩展"。它是与正在处理的块交互的轮密钥。

在密钥、IV、明文和密文的编码方面,AES加密不使用编码。AES加密使用二进制数据——一个8位字节的序列。

您需要在解密平台上使用相同的二进制密钥、二进制IV和二进制密文来生成原始的二进制明文。

当您在字符编码和二进制之间进行转换时,您并不总是保证进行往返转换。也就是说,不是所有的字节序列都可以转换为UTF-8字符的字符串。

然而,如果您将UTF-8明文视为二进制数据,并对其进行加密,然后将密文传输为二进制,例如,通过将其编码为base64以保留数据的二进制表示,那么当您在解密平台上进行base64解码以重新构造二进制密文并解密时,得到的二进制明文将是原始的UTF-8字符数据。

在加密和解密方面始终将密钥、IV、明文和密文视为二进制数据。明文是二进制数据,可能恰好是UTF-8,或者ASCII的某种变体,或者UTF-16BE,等等。该密文很可能不是上述任何一种,或者纯属偶然。