【问题标题】:AES Encryption and decryption for android and iOS gives wrong outputAndroid 和 iOS 的 AES 加密和解密给出错误的输出
【发布时间】:2026-02-06 02:30:01
【问题描述】:

Android 代码:

私有静态最终字符串 ALGORITHM = "AES/ECB/PKCS5Padding";

private static final String KEY = "SixteenCharacter";

加密:

private static byte[] encrypt(final byte[] key, final byte[] originalData) {
    try {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(originalData);
        return encrypted;
    } catch (Exception ex) {
       ex.printStackTrace();
       return new byte[0];
    }
}

解密:

private static byte[] decrypt(final byte[] key, final byte[] encryptedData) {
    try {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        SecretKeySpec skeySpec = new SecretKeySpec(key, ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] original = cipher.doFinal(encryptedData);
        return original;
    } catch (Exception ex) {
        ex.printStackTrace();
        return new byte[0];
    }
}

iOS 代码:

静态让 KEY = "SixteenCharacter"

私有静态 let iv: Array = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]

加密:

static func getEncryptedString(normal: String?, key: String, options: Int = kCCOptionPKCS7Padding) -> String {
    guard let normal = normal else { return "" }
    if let keyData = key.data(using: String.Encoding.utf8),
       let data = normal.data(using: String.Encoding.utf8),
       let cryptData    = NSMutableData(length: Int((data.count)) + kCCBlockSizeAES128) {
        let keyLength              = size_t(kCCKeySizeAES128)
        let operation: CCOperation = UInt32(kCCEncrypt)
        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
        let options:   CCOptions   = UInt32(options)
        var numBytesEncrypted :size_t = 0
        let cryptStatus = CCCrypt(operation,
                                  algoritm,
                                  options,
                                  (keyData as NSData).bytes, keyLength,
                                  iv,
                                  (data as NSData).bytes, data.count,
                                  cryptData.mutableBytes, cryptData.length,
                                  &numBytesEncrypted)
        
        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            cryptData.length = Int(numBytesEncrypted)
            var base64cryptString = cryptData.base64EncodedString(options: .lineLength76Characters)
            //base64cryptString = base64cryptString.replacingOccurrences(of: "/", with: "_")
                        .replacingOccurrences(of: "+", with: "-")
            return base64cryptString
        }
        else {
            return normal
        }
    }
    return normal
}

解密:

static func getDecryptedString(normal: String?, key: String, options: Int = kCCOptionPKCS7Padding) -> String {
    guard var normal = normal else { return "" }
    //normal = normal.replacingOccurrences(of: "_", with: "/").replacingOccurrences(of: "-", with: "+")
    if let keyData = key.data(using: .utf8),
       let data = NSData(base64Encoded: normal, options: .ignoreUnknownCharacters),
       let cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {
        let keyLength              = size_t(kCCKeySizeAES128)
        let operation: CCOperation = UInt32(kCCDecrypt)
        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
        let options:   CCOptions   = UInt32(options)
        var numBytesEncrypted :size_t = 0
                    let cryptStatus = CCCrypt(operation,
                                  algoritm,
                                  options,
                                  (keyData as NSData).bytes, keyLength,
                                  iv,
                                  data.bytes, data.length,
                                  cryptData.mutableBytes, cryptData.length,
                                  &numBytesEncrypted)
        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            cryptData.length = Int(numBytesEncrypted)
            let unencryptedMessage = String(data: cryptData as Data, encoding:String.Encoding.utf8)
            if let unencryptedMessage = unencryptedMessage, !unencryptedMessage.isEmpty {
                return unencryptedMessage
            }
        }
        else {
            return normal
        }
    }
    return normal
}

由于我之前没有使用过 AES 加密,我不知道我哪里出错了 我在互联网上看到了很多解决方案,但还没有运气

Android 代码已经完成,我唯一的办法就是修改 iOS 代码!

提前致谢!

【问题讨论】:

    标签: android ios swift encryption


    【解决方案1】:

    您正在跨两个不同的系统工作。这意味着您不能依赖系统默认值,它们可能会有所不同。您需要指定所有内容:密钥、IV、填充、字符编码等。 Crypto 设计为即使是很小的不匹配也会失败,因此您必须检查所有内容以确保它在两个系统中都匹配。例如,IIRC iOS 和 Java 使用不同的行尾字符。如此简单的事情可能会导致解密失败。

    如果没有什么明显的,则以二进制/十六进制查看双方的所有输入,以确保所有内容完全匹配。

    您正在使用 ECB 模式。这是不安全的,除非非常特殊和罕见的情况,否则不应使用。最好使用CBC或CTR模式。如果您还需要身份验证,请尝试 GCM 模式。

    【讨论】:

    • 我明白了你在说什么,但我无法理解代码有什么问题,这就是为什么我发布了代码 android 和 iOS,因为 android 代码已经完成并且不能已更改,我无法将模式从 ECB 更改为任何其他模式。无论如何,感谢您的回复!