使用3DES加密时,遇到后端加解密数据与iOS加解密数据不一致的问题,特此记录下。
后端使用的算法algorithm
参数是ecb
,iOS端使用kCCOptionECBMode
或者kCCOptionPKCS7Padding
时,如果加密的原始数据全是数字类型时,可以得到相同的加解密结果。但是,当原始数据包含特殊字符或者字母时就跟后端得到的不一致了,正确的设置是使用(kCCOptionECBMode + kCCOptionPKCS7Padding)
。
在3DES加密中,key值是24位字符串,一般我们是将原始key值经过md5加密后截取前24位作为3DES加解密的key来使用。
加解密代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| func tripleDESEncryptOrDecrypt(op: CCOperation,key: String) -> String? { let iv:String? = "" let keyData: NSData = (key as NSString).data(using: String.Encoding.utf8.rawValue)! as NSData let keyBytes = UnsafeRawPointer(keyData.bytes) var data: NSData = NSData() if op == CCOperation(kCCEncrypt) { data = (self as NSString).data(using: String.Encoding.utf8.rawValue)! as NSData } else { data = NSData(base64Encoded: self, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters)! } let dataLength = size_t(data.length) let dataBytes = UnsafeRawPointer(data.bytes) let cryptData = NSMutableData(length: Int(dataLength) + kCCBlockSize3DES) let cryptPointer = UnsafeMutableRawPointer(cryptData!.mutableBytes) let cryptLength = size_t(cryptData!.length) let viData :NSData = (iv! as NSString).data(using: String.Encoding.utf8.rawValue)! as NSData let viDataBytes = UnsafeRawPointer(viData.bytes) let keyLength = size_t(kCCKeySize3DES) let operation: CCOperation = UInt32(op) let algoritm: CCAlgorithm = UInt32(kCCAlgorithm3DES) let options: CCOptions = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding) var numBytesCrypted :size_t = 0 let cryptStatus = CCCrypt(operation, algoritm, options, keyBytes, keyLength, viDataBytes, dataBytes, dataLength, cryptPointer, cryptLength, &numBytesCrypted) if UInt32(cryptStatus) == UInt32(kCCSuccess) { cryptData!.length = Int(numBytesCrypted) if op == CCOperation(kCCEncrypt) { let base64cryptString = cryptData?.base64EncodedString(options: []) return base64cryptString } else { let base64cryptString = String.init(data: cryptData! as Data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) return base64cryptString } } return nil } }
|
测试数据:
1 2 3 4 5 6 7 8 9 10 11 12
| var key = "012438BF-4E53-458F-8A07-D7DDFC8FA1F8190808173932337_" let keyStr = md5String(text: key) key = String(keyStr.prefix(24))
let text = "1234qwer" var encryptText:String? var decrptText:String? encryptText = text.tripleDESEncryptOrDecrypt(op: CCOperation(kCCEncrypt), key: key) decrptText = "labWVwRfO4BSWJA2swHTOg==".tripleDESEncryptOrDecrypt(op: CCOptions(kCCDecrypt), key: key) print("加密结果:"+(encryptText ?? "加密失败")) print("解密结果:"+(decrptText ?? "解密失败"))
|