Swift中3DES解密方法失效返回Null问题求助
Swift 3DES解密返回Null问题(与C#/Android兼容)
嘿,作为Swift新手碰到跨平台加密兼容的问题确实挺头疼的,我帮你梳理下常见的坑和解决方案~
问题背景
我目前有一套3DES加密解密逻辑,已经验证过C#和Android端的加密解密都能正常工作且互相兼容,但在Swift端实现的解密方法始终返回Null。尝试多次调整都没能解决,希望能得到帮助。
测试用密文:
"5lg3yg7Q+Y8="
现有Swift解密代码片段:
func tripleDesDecrypt(PlainString :String) -> String? { let md5Data = "FIFEDCBA98765432104AABFD" if let keyData = md5Data.data(using: String.Encoding.ut...
跨平台3DES兼容的常见坑
3DES跨平台出问题,大概率是以下几个环节没对齐:
- 密钥处理逻辑不一致:C#/Android可能对密钥做了MD5哈希后截取/拼接成24字节(3DES要求的密钥长度),Swift端可能哈希方式、编码或截取逻辑错了
- 填充/加密模式不匹配:比如C#用
PKCS7Padding+ECB模式,Swift端却没设置填充,或者用了CBC模式却没传IV - 密文解码错误:你的密文是Base64格式,Swift解密前必须正确解码成Data
- 字符串编码不统一:解密后转字符串时,要用和加密端完全一致的编码(比如UTF-8)
修正后的完整实现(适配C#/Android常见配置)
我写了一个符合常见跨平台兼容要求的3DES解密方法,你可以根据自己的实际加密逻辑调整:
import CommonCrypto func tripleDesDecrypt(cipherBase64: String) -> String? { // 1. 对齐密钥处理:和C#/Android一致,先对密钥字符串做MD5哈希,再拼接成24字节(3DES要求) let originalKey = "FIFEDCBA98765432104AABFD" guard let keyData = originalKey.data(using: .utf8) else { print("密钥转Data失败") return nil } // 计算MD5哈希 var md5Hash = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH)) CC_MD5(keyData.bytes, CC_LONG(keyData.count), &md5Hash) // 3DES需要24字节密钥,把MD5结果拼接一次后取前24位(很多C#实现会这么做) var keyBytes = md5Hash + md5Hash keyBytes = Array(keyBytes.prefix(24)) // 2. 解码Base64格式的密文 guard let cipherData = Data(base64Encoded: cipherBase64) else { print("密文Base64解码失败") return nil } // 3. 配置3DES解密参数:ECB模式+PKCS7填充(和C#/Android保持一致) let operation = CCOperation(kCCDecrypt) let algorithm = CCAlgorithm(kCCAlgorithm3DES) let options = CCOptions(kCCOptionECBMode | kCCOptionPKCS7Padding) // 初始化解密后的数据容器 var decryptedData = Data(count: cipherData.count + kCCBlockSize3DES) var decryptedLength = 0 // 执行解密 let status = CCCrypt(operation, algorithm, options, keyBytes, keyBytes.count, nil, // ECB模式不需要IV向量 cipherData.bytes, cipherData.count, decryptedData.mutableBytes, decryptedData.count, &decryptedLength) // 检查解密是否成功 guard status == kCCSuccess else { print("解密失败,错误码:\(status)") return nil } // 截取实际有效的解密数据(去掉多余的填充位) decryptedData = decryptedData.prefix(decryptedLength) as Data // 4. 转成字符串(用UTF-8编码,和加密端对齐) return String(data: decryptedData, encoding: .utf8) } // 测试调用 let testCipherText = "5lg3yg7Q+Y8=" if let decryptedResult = tripleDesDecrypt(cipherBase64: testCipherText) { print("解密成功:\(decryptedResult)") } else { print("解密失败,返回Null") }
按需调整的关键点
- 密钥处理:如果你的C#/Android代码不是用MD5哈希后拼接成24字节,一定要完全对齐原逻辑。比如原逻辑是直接用24字节的密钥字符串,那你就不需要做MD5哈希,直接转成Data即可。
- 加密模式与IV:如果原加密用的是CBC模式,你需要添加对应的IV向量(必须是8字节,3DES的块大小),并在
CCCrypt中传入IV的字节数据。 - 填充模式:如果原加密用的是
ZeroPadding,需要去掉kCCOptionPKCS7Padding选项,并且解密后手动去掉末尾的0字节。 - 编码格式:如果加密端用的是GBK等非UTF-8编码,转字符串时要对应调整(不过大部分场景下都是UTF-8)。
内容的提问来源于stack exchange,提问作者Adeel Aijaz
相关产品推荐
相关产品推荐

