Swift用CryptoSwift解密后报NSCocoaErrorDomain Code=3840错误如何解决
问题原因
你遇到的NSCocoaErrorDomain Code=3840 "Garbage at end."错误本质是AES解密后的数据末尾残留了不属于JSON内容的\0填充字节,JSON解析器无法识别这些非法字符抛出报错。
出现填充字节的原因是AES为块加密算法,要求原始数据长度必须是加密块大小(默认128位即16字节)的整数倍,不足时服务端会在数据末尾填充占位字节,你当前场景使用的是\0作为占位符的零填充方案,CryptoSwift解密时如果没有匹配对应填充规则,就不会自动移除这些填充位。
解决方案
方案1:手动移除解密数据的尾随空字节(兼容性最高)
解密得到原始Data后,先切掉末尾所有的\0字节,再用于JSON解析,修改代码如下:
let decryptedData = Data(try aes.decrypt(encryptedData.bytes)) // 新增:移除末尾的空字节填充 let trimmedData = decryptedData.prefix { $0 != 0 } // 用处理后的trimmedData做后续操作 let decryptedText = String(data: trimmedData, encoding: .utf8) let jsonData = try JSON(data: trimmedData)
方案2:解密时明确指定填充规则和服务端对齐
初始化AES实例时,根据服务端的填充配置明确指定padding参数,CryptoSwift会自动移除填充位:
如果服务端使用零填充:
let aes = try AES(key: self.keyForCrypting, blockMode: CBC(iv: iv), padding: .zeroPadding)
如果服务端使用PKCS7填充(常用标准方案):
let aes = try AES(key: self.keyForCrypting, blockMode: CBC(iv: iv), padding: .pkcs7)
填充规则对齐后,解密得到的数据就不会残留多余的填充字节,可直接用于JSON解析。
补充说明
两种方案可以同时使用,手动移除尾随空字节可以在两端填充规则不一致时兜底,避免解析失败。
内容的提问来源于stack exchange,提问作者mahen3d
相关产品推荐
相关产品推荐

