You need to enable JavaScript to run this app. Swift中CommonCrypto解密URLSession获取的AES128-CBC数据始终返回nil
优惠活动
大模型
产品
解决方案
定价
更多

Swift中CommonCrypto解密URLSession获取的AES128-CBC数据始终返回nil

解密失败的核心根因

你通过打印看到接口返回的字符串和自测加密结果一致,是视觉层面的等价,两者传递给解密函数的二进制数据本质完全不同:

  • 自测环节encrypt(string: "Hello")返回的dataEncrypt:是AES加密直接生成的原始密文二进制块。当你把这个原始密文做Base64编码时,才会展示成你看到的lG7Bqk0nwx732eOQLAzhqQ==字符串,这个原始密文没有经过额外编码,直接传入CCCrypt可以正常完成解密。
  • 接口返回的Data:是服务端把原始密文经过Base64编码后生成的字符串对应的ASCII字节流。这部分Data存储的是组成Base64字符串的每个字符的编码值,不是AES算法要求的原始密文块,直接传给解密方法时,会因为密文格式不匹配导致CCCrypt执行失败,最终返回nil。
修复步骤
  1. 拿到接口返回的原始Data后,先完成两层转换:
    • 把接口返回的Data转成UTF8字符串,拿到服务端返回的Base64格式密文
    • 对Base64字符串做解码,得到AES算法可直接处理的原始密文二进制Data
  2. 将解码后的原始密文Data传入现有的解密方法即可正常解密

修正后的接口测试代码参考:

let aes128 = AES()
if let url = URL(string: "\(localhostUrl)/payment") {
    URLSession.shared.dataTask(with: url) { data, response, error in
        guard let data = data,
              // 接口返回的UTF8字符串转原始Base64密文,同时清理可能存在的换行、空格
              let base64Cipher = String(data: data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines),
              // 将Base64字符串转成解密需要的原始密文Data
              let cipherData = Data(base64Encoded: base64Cipher) else {
            return
        }
        // 传入原始密文执行解密
        let decryptResult = aes128?.decrypt(data: cipherData)
        print(decryptResult) // 可正常输出"Hello"
    }.resume()
}
原有业务逻辑的调整提示

你原本的getTestAllPayments方法直接调用JSONDecoder解析接口返回的Data,因为完全跳过了「Base64解码 → AES解密 → 明文转JSON模型」的流程,即使接口返回数据正确,也无法解析出正常的[Payment]模型,需要在JSON解码前补上上述的Base64解码、AES解密步骤,把解密得到的明文Data传入JSONDecoder才能正常工作。


内容的提问来源于stack exchange,提问作者Kevin Kentie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.26 11:27:00