跨平台AES加密如何工作?

时间:2011-12-29 23:35:50

标签: php objective-c cryptography cross-platform aes

我已经能够在php和objective-c代码中成功加密和解密AES-256。我不会在这里发布任何代码,因为我已经尝试了很多种类,但没有工作。我不知道这些加密函数是如何工作的...... AES是一种标准化的算法,所以为什么它在我的想法中不起作用归结为

a)iv
b)一些编码错误

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

如果某人的AES功能同时适用于php和objective-c,那将是非常好的,但如果没有,那么理解导致这些不同结果的原因将有所帮助。

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

1)在密钥和明文/密文方面使用什么编码是否重要?基本上我猜测它不是纯文本的问题,因为我将使用的所有字符(至少在测试期间)是标准的ASCII符号。但是,让我们说php字符串是ASCII,我在objective-c中使用UTF8 ...我不知道如果php使用ASCII或如果字节即。两者之间的关键是不同的。

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

3)根据算法,块大小和密钥大小有什么区别? (再次纠正如果错误)基本上他们都是相同的算法只是不同的参数?使用256位密钥和128位密钥只是传递了哪个密钥

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

谢谢, 利亚

2 个答案:

答案 0 :(得分:6)

要使解密正常工作,一切必须完全相同。相同的密钥,相同的IV,相同的模式。特别是密钥必须相同。字节的字节相同。有点相同。如果密钥的一位不正确,AES的设计无法正确解密。

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

看看你的三个问题:

1)对于明文编码,你会得到你输入的内容:UTF-8输入,UTF-8输出。如果要转换为不同的编码,则必须在解密后执行此操作。

2)你是对的,ECB不需要IV,但ECB模式泄漏信息,应该避免。使用CBC或CTR模式,两端使用相同的模式。 IV与块大小相关联,因此对于AES,IV始终为16字节或128位。您不能保证ASCII和UTF-8是相同的。 UTF可能在一开始就有BOM。 ASCII可能在末尾有一个C风格的零字节。不要以字符的形式思考,用字节来思考。一切都必须在字节级别匹配。在CBC模式下,有故障的IV会破坏第一个块,但会解密后续块。

3)AES的块大小固定为128位,无法更改。密钥大小受限制较少,可以是128,192或256位。在实践中,大多数人似乎使用128位或256位。块是一个方便大小的处理单元,它以非常低的水平内置在密码中。键确定在处理过程中对块执行的操作。这为密钥提供了更大的灵活性。您输入的密钥用于构建一些内部结构,即“圆形键”。此过程称为“密钥扩展”。圆键与正在处理的块交互。因为密钥是间接使用的,所以它有多大的灵活性。

答案 1 :(得分:0)

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

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

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

但是,如果将UTF-8明文视为二进制数据并加密,然后将密文作为二进制传输,例如,将其编码为base64以保留二进制表示形式数据,然后当你base64-decode重构解密平台上的二进制密文并解密时,生成的二进制明文将是原始的UTF-8字符数据。

始终将密钥,IV,明文和密文视为加密和解密方面的二进制数据。明文是二进制数据,可能恰好是UTF-8,或ASCII的一些变体,或UTF-16BE等。密文可能不是那些,或者恰好是偶然的一个。< / p>