【问题标题】:How does cross platform AES encryption work?跨平台 AES 加密如何工作?
【发布时间】:2012-01-30 06:40:28
【问题描述】:

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

a) 静脉注射
b) 一些编码错误

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

如果有人拥有在 php 和 Objective-c 中都可以使用的 AES 函数,那就太好了,但如果没有,任何帮助理解导致这些不同结果的原因将不胜感激。

如果您想要一个更狭窄的问题,它是关于此 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 编码在应用程序之间传输字符串以进行测试)

谢谢, 以利亚

【问题讨论】:

  • ... I could not get openssl to work on the Mac with an error 那么,你为什么不问一个关于那个特定错误的问题呢?
  • 因为在这一点上,我什至认为这行不通。我在 NSData AES256EncryptWithKey 上使用了一个类别,这也适用于 Mac 上的解码。我得到的“特殊错误”是代码,一旦在objective-c中加密并以base-64打印到控制台,就不会使用php解密。
  • 对不起,最后一句话不相关

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


【解决方案1】:

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

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

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

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

在加密和解密方面,始终将密钥、IV、明文和密文视为二进制数据。明文是二进制数据,可能恰好是 UTF-8,或 ASCII 的某些变体,或 UTF-16BE 等。密文可能不是这些,或者碰巧只是偶然的其中之一。

【讨论】:

    【解决方案2】:

    为了使解密正常工作,一切必须完全相同。相同的键,相同的 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 位。块是一个大小方便的处理单元,它以非常低的级别内置在密码中。密钥决定了在处理过程中对块做了什么。这为密钥提供了更大的灵活性。您输入的密钥用于构建一些内部结构,即“圆形密钥”。这个过程称为“密钥扩展”。与正在处理的块交互的是轮密钥。因为密钥是间接使用的,所以它可以有多大的灵活性。

    【讨论】:

    • 谢谢。我将转储十六进制值并尝试匹配它们。至于#3,不过,你说的有道理,但请解释一下本页最后一个标记为-2 的帖子(stackoverflow.com/questions/8276833/…)。这篇文章的否定意味着在 MCRYPT_RIJNDAEL_128 中引用了块侧......但 php 也有 MCRYPT_RIJNDAEL_256。因此,该用户在 php 中使用 MCRYPT_RIJNDAEL_128,在 Objective-c 中使用 AES256DecryptWithKey。这意味着存在 256 位块端(256 php 常量)。
    • Rijndael 是 AES 的超集。 Rijndael 的块大小可以从 128 位向上,以 32 位的倍数计算。 AES 仅限于 128 位块。更常见的情况是,人们在说“Rijndael”时指的是 AES,而 -128 或 -256 是密钥大小,而不是块大小。乔纳森的评论可能是正确的。
    • 这对超集很有意义。但是,您似乎不正确地将 -128 -256 作为密钥大小。作者使用带有 Rijndael-128 的 32 位密钥,并将 php 算法与 Objective-c 中的 AES256... 函数相匹配。我会花更多时间在这个项目上,看看进展如何。
    • 好消息:我能够解码在 Objective-C 中加密的 php 代码(AES256DecryptWithKey) 12)我的测试密钥。我发现 ASCII 和 UT8 按位完全相同。转换为十六进制时,两者都由 32 个 8 字符部分组成,并且 ASCII 向后兼容。
    • 供任何人参考,我发现带有 null IV 的 AES256DecryptWithKey 和 CCCrypt 都在 16 位 / 16 字符长度 iv 的 CBC 模式下工作。创建这个 iv 的 PHP 代码: $iv2 = ''; for($i=0;$i
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    相关资源
    最近更新 更多