【问题标题】:Decrypt android AES example on iOS在 iOS 上解密 android AES 示例
【发布时间】:2014-04-07 22:04:26
【问题描述】:

我有一个 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];

【问题讨论】:

  • iOS 和 android 必须使用相同的加密模式和填充才能正常工作。
  • 您需要学习一点加密知识,确定 Android 代码使用的选项和输入,并将它们复制到 iOS 代码中。 CommonCrypto 是你的朋友,认识他吧。在不理解的情况下使用加密可能会产生可靠的结果。
  • 确实如此。但目标不是完全保护数据,而是延迟潜在的黑客攻击。我只想为一个临时项目提供一个加密的提要。
  • 我刚刚在stackoverflow.com/questions/40421146/… 中发布了一个可以接受的答案。

标签: android ios encryption cryptography aes


【解决方案1】:

首先,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相同。

【讨论】:

    【解决方案2】:

    提示:

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

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

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

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

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

    【讨论】:

    • 请点赞并勾选我的答案作为正确答案:)
    【解决方案3】:

    这可能是因为公钥不同。

    有两件事是加密存储的。第一个是用户名/密码,第二个是消息本身。当您正确输入密码后,系统会使用您的密码和公钥对消息进行解密。

    之所以称它为公钥,是因为对于相同的加密方法,密钥是相同的。

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

    或者您可以使用更简单的方法,例如公平竞赛。

    【讨论】:

      【解决方案4】:

      其他答案指出的是正确的,它可以归结为不同的是密钥大小/模式/填充。 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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-21
        • 2013-12-07
        • 2011-10-10
        • 2016-09-22
        • 1970-01-01
        相关资源
        最近更新 更多