PHP 服务器和 iOS 上的 AES Rijndael 有时会生成不同的密码

发布于 2024-12-18 03:47:10 字数 1664 浏览 4 评论 0原文

我正在使用 Jim Dovey 的 NSData+AESCrypt 类别和 Michael Sedlaczek 的 NSString+AESCrypt (2011-02-22)。

在 PHP 上,我有一个简单的脚本:

<?php
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = '01234567890123456789012345678901';
$plaintext = "myworda";

$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_ECB);
$base64encoded_ciphertext = base64_encode($ciphertext);
echo "ciphertext: ".$base64encoded_ciphertext."<br/>";
?>

在 ObjC 中:

NSString *key = @"01234567890123456789012345678901";
NSString *plaintext = [@"+l56Ia4yyK19D2x2+oCXuw==" AES256DecryptWithKey: key];
NSLog(@"plaintext: %@", plaintext);

我更改 PHP 中的变量 $plaintext,运行脚本并将输出密码复制并粘贴到 Objective-c 中以解密它。

并且:

  1. “myword”给我“+l56Ia4yyK19D2x2+oCXuw==”,我在iOS上解密并得到“myword”[OK]

  2. “早上好”给了我“5UdImsV1pQs60ovXmH74HQ==”,我解密并在 iOS 上得到“早上好”[OK]

  3. “Schröder”给了我“KqNSCE8nGsYUYVdGZ2tnMw==”,我解密并在 iOS 上得到“Schröder”[OK]
  4. “Schröder”给我“KqNSCE8nGsYUYVdGZ2tnMw==”,我解密并在 iOS 上得到“Schröder”[OK]
  5. “非常长的文本”给我“lsa+QF3IHQnAFiOjl2Heyg==”我解密并在 iOS 上得到“非常长的文本”[好的]
  6. “非常非常非常长的文本”给了我“kl/ThEyuyUMmKSqU4/fJSzzJOyvsXrGRt5/zsnqjQww=”并且我无法在 iOS 上解密它 [失败]

为什么 #5 失败?如果我尝试使用 Xcode 加密“非常非常非常长的文本”,我会得到“kl/ThEyuyUMmKSqU4/fJS90UZoJ73S4gox2uCoWoIL8=”注意: 吉隆坡/ThEyuyUMmKSqU4/fJS == 吉隆坡/ThEyuyUMmKSqU4/fJS zzJOyvsXrGRt5/zsnqjQww != 90UZoJ73S4gox2uCoWoIL8=

但更进一步,在 Xcode 上加密“早上好”会得到“hVq1AuR8PAXSOztK26pmMw==”,而 PHP 会给出“5UdImsV1pQs60ovXmH74HQ==”,但 Xcode 会将两者解密为使用相同的键“早上好”。

请帮忙。

I'm using NSData+AESCrypt category by Jim Dovey and NSString+AESCrypt by Michael Sedlaczek (2011-02-22).

And on PHP I have a simple script:

<?php
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = '01234567890123456789012345678901';
$plaintext = "myworda";

$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_ECB);
$base64encoded_ciphertext = base64_encode($ciphertext);
echo "ciphertext: ".$base64encoded_ciphertext."<br/>";
?>

In ObjC:

NSString *key = @"01234567890123456789012345678901";
NSString *plaintext = [@"+l56Ia4yyK19D2x2+oCXuw==" AES256DecryptWithKey: key];
NSLog(@"plaintext: %@", plaintext);

I change the variable $plaintext in PHP, run script and copy and paste the output-cipher to the Objective-c to decrypt it.

And:

  1. "myword" gives me "+l56Ia4yyK19D2x2+oCXuw==" and I decrypt in and get "myword" on iOS [OK]

  2. "good morning" gives me "5UdImsV1pQs60ovXmH74HQ==" and I decrypt in and get "good morning" on iOS [OK]

  3. "Schröder" gives me "KqNSCE8nGsYUYVdGZ2tnMw==" and I decrypt in and get "Schröder" on iOS [OK]
  4. "Schröder" gives me "KqNSCE8nGsYUYVdGZ2tnMw==" and I decrypt in and get "Schröder" on iOS [OK]
  5. "very long text" gives me "lsa+QF3IHQnAFiOjl2Heyg==" and I decrypt in and get "very long text" on iOS [OK]
  6. "very very very very long text" gives me "kl/ThEyuyUMmKSqU4/fJSzzJOyvsXrGRt5/zsnqjQww=" and I cannot decrypt it on iOS [FAIL]

Why #5 fails? If I try to encrypt "very very very very long text" using Xcode, I get "kl/ThEyuyUMmKSqU4/fJS90UZoJ73S4gox2uCoWoIL8=" notice that:
kl/ThEyuyUMmKSqU4/fJS == kl/ThEyuyUMmKSqU4/fJS
zzJOyvsXrGRt5/zsnqjQww != 90UZoJ73S4gox2uCoWoIL8=

But going further, encrypting "good morning" on Xcode gives me "hVq1AuR8PAXSOztK26pmMw==", while PHP gave "5UdImsV1pQs60ovXmH74HQ==", but Xcode decrypts both to "good morning" using the same key.

Please help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

画离情绘悲伤 2024-12-25 03:47:10

您的 PHP 代码正在使用 ECB 模式。我看不到你在 ObjC 中设置模式的位置。想必您正在使用其默认模式。 ObjC 默认模式可能不是 ECB,更有可能是 CBC。另请注意,只要您的明文等于或小于 16 个字节(即一个块或更少),解密就会起作用。当它大于 16 字节(即它扩展到第二个块)时,它会失败。

我怀疑 ObjC 默认是 CBC 模式,IV 为零。这就像仅适用于第一个区块的 ECB,而对于第二个及后续区块则有所不同。

ECB 模式不安全并且会泄露信息。请改用具有指定 IV 的 CBC 模式。至少更改您的 PHP 代码以使用 CBC 模式而不是 ECB 模式。

Your PHP code is using ECB mode. I cannot see where you are setting the mode in ObjC. Presumably you are using its default mode. It is possible that the ObjC default mode is not ECB, more likely CBC. Also notice that whenever your plaintext is 16 bytes or less (that is one block or less) the decryption works. When it is greater than 16 bytes (that is it extends into a second block) it fails.

I suspect that the ObjC default is CBC mode with a zero IV. That will act as if it is ECB for the first block only, and differ for the second and subsequent blocks.

ECB mode is unsafe and leaks information. Use CBC mode with a specified IV instead. At the very least change your PHP code to use CBC mode instead of ECB mode.

白首有我共你 2024-12-25 03:47:10

您可以使用 MCRYPT_RIJNDAEL_128 加密消息,这将为您提供 128 位(即 16 字节)的块大小。
您会注意到非常非常非常长的文本大于 16 个字节。

所以我猜你在 ios 上解密使用了不同的块大小。我对ios不熟悉,但是AES256DecryptWithKey似乎表明它使用256位的块大小。

尝试在 PHP 代码中使用 MCRYPT_RIJNDAEL_256 ,或更改 ios 代码以使用 AES128DecryptWithKey (我不知道是否存在,同样,我不知道 ios)

You encrypt the message using MCRYPT_RIJNDAEL_128 which gives you a block size of 128 bits, or 16 bytes.
You'll notice that very very very very long text is larger than 16 bytes.

So I'm guessing you're decryption on ios uses a different block size. I'm not familiar with ios, but AES256DecryptWithKey seems to indicate it uses a block size of 256 bits.

Try using MCRYPT_RIJNDAEL_256 in your PHP code, or change the ios code to use AES128DecryptWithKey (I don't know if that exist, again, I don't know ios)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文