解密iOS上的Android AES示例

时间:2014-03-05 17:19:22

标签: android ios encryption cryptography aes

我有一个AES加密/解密的Android示例。

https://github.com/itog/CryptoSample/blob/master/src/com/pigmal/android/ex/crypto/Crypto.java#L35

我想在iOS上解密这个。看起来几乎不可能。我发现这更容易,但失败了:

https://github.com/Gurpartap/AESCrypt-ObjC

我甚至没有从base64解码中得到很好的回复。这是我的代码:

NSData *encryptedData = [NSData base64DataFromString:encrypted];
// returns null
NSData *decryptedData = [encryptedData decryptedAES128DataUsingKey:[[CRYPT_SEED dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash] error:&error];
NSString* result = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];

4 个答案:

答案 0 :(得分:2)

首先,AES是对称密码算法,它需要使用完全相同的密钥进行消息加密以及消息解密。

我已经检查了你的示例代码,这些是真正困扰我的事情:

  • 不同的密钥:Android示例不提供应该使用的AES密钥的任何getter或setter。如果没有它,您将无法在Android和iOS上使用相同的AES密钥。
  • 不同的密钥大小:Android示例似乎使用AES-128,但iOS示例似乎使用AES-256
  • 不同的密码模式:iOS示例使用CBC cipher mode,因此您还需要在设备之间交换IV (initialization vector)。但是,在Android示例中,我没有看到任何提供/获取IV的界面。

我相信这些是你无法让它发挥作用的主要原因。如果您想使用AES,则需要在两台设备上修改代码使用相同的密钥在两台设备上使用相同的cipher mode ,在两台设备上使用相同的padding

答案 1 :(得分:2)

提示:

  • 您可以使用第三方库来执行此操作。根据库的不同,它可能是跨平台的,因此在不同平台上的相同调用将返回相同的结果。

安全黑匣子: https://www.eldos.com/sbb/platforms.php#product

加密++ http://www.cryptopp.com

  • 您可以编译测试AES例程,以确保Android和iOS上的AES加密和解密例程都能产生相同的结果。

  • 如果正确编码和解码,您可以检查Base64。有时它可能是Unicode(UTF16)iOS和非Unicode(UTF8)Android问题。当我这样做时,这发生在我身上。

答案 2 :(得分:0)

这可能是因为公钥不同。

加密存储有两件事。第一个是用户名/密码,第二个是消息本身。正确输入密码后,将使用密码和公钥解密邮件。

我们将其称为公钥的原因是,对于相同的加密方法,密钥是相同的。

因此,我认为,也许您应该寻找一个将公钥设置为您选择的字符串的过程。

或者您可以使用更简单的方法,例如fairplay。

答案 3 :(得分:0)

其他答案所指出的是真实的,它可能会有不同的关键尺寸/模式/填充。 BASE64编码的类型也可能存在问题。在Android上,有几个不同的标志可以产生微妙的不同输出。我发现Base64.NO_WRAP可以使用了。

我也遇到过与AESCrypt-ObjC类似的问题,默认情况下它使用空白IV,而在Android / Java上,如果您没有指定一个随机的生成,则会出现问题。

这里是我如何指定空白IV以便iOS可以解密:

private static byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);

cipherText = cipher.doFinal(stuffIWantSafe.getBytes("UTF-8"));

String encodedCipherText = Base64.encodeToString(cipherText, Base64.NO_WRAP);

免责声明:我不建议从安全的角度来看空白IV,以便更好地使每个消息的IV发生变化

*更新:刚刚发布了AESCrypt的Android version