对于字符串的加密解密,可以给String类扩展方法,方便使用
Swift中使用3DES/sha1/MD5加密解密算法 必须要引入这个库 - 在桥接文件中
#import <CommonCrypto/CommonCrypto.h>
3DES的加密是可逆的, sha1和MD5的是不可逆的
extension String {
/**
3DES的加密过程 和 解密过程
- parameter op : CCOperation: 加密还是解密
CCOperation(kCCEncrypt)加密
CCOperation(kCCDecrypt) 解密
- parameter key: 专有的key,一个钥匙一般
- parameter iv : 可选的初始化向量,可以为nil
- returns : 返回加密或解密的参数
*/
func threeDESEncryptOrDecrypt(op: CCOperation,key: String,iv: String) -> String? {
// Key
let keyData: NSData = (key as NSString).data(using: String.Encoding.utf8.rawValue) as NSData!
let keyBytes = UnsafeMutableRawPointer(mutating: 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 = UnsafeMutableRawPointer(mutating: 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 = UnsafeMutableRawPointer(mutating: viData.bytes)
// 特定的几个参数
let keyLength = size_t(kCCKeySize3DES)
let operation: CCOperation = UInt32(op)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithm3DES)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)
var numBytesCrypted :size_t = 0
let cryptStatus = CCCrypt(operation, // 加密还是解密
algoritm, // 算法类型
options, // 密码块的设置选项
keyBytes, // 秘钥的字节
keyLength, // 秘钥的长度
viDataBytes, // 可选初始化向量的字节
dataBytes, // 加解密内容的字节
dataLength, // 加解密内容的长度
cryptPointer, // output data buffer
cryptLength, // output data length available
&numBytesCrypted) // real output data length
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData!.length = Int(numBytesCrypted)
if op == CCOperation(kCCEncrypt) {
let base64cryptString = cryptData?.base64EncodedString(options: .lineLength64Characters)
return base64cryptString
}
else {
// let base64cryptString = NSString(bytes: cryptPointer, length: cryptLength, encoding: NSUTF8StringEncoding) as? String // 用这个会导致返回的JSON数据格式可能有问题,最好不用
let base64cryptString = NSString(data: cryptData! as Data, encoding: String.Encoding.utf8.rawValue) as? String
return base64cryptString
}
} else {
print("Error: \(cryptStatus)")
}
return nil
}
/*sha1不可逆加密**/
func sha1() -> String {
let data = self.data(using: String.Encoding.utf8)!
var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))
data.withUnsafeBytes {
_ = CC_SHA1($0, CC_LONG(data.count), &digest)
}
let hexBytes = digest.map { String(format: "%02hhx", $0) }
return hexBytes.joined()
}
func MD5() -> String {
let str = self.cString(using: String.Encoding.utf8)
let strLen = CUnsignedInt(self.lengthOfBytes(using: String.Encoding.utf8))
let digestLen = Int(CC_MD5_DIGEST_LENGTH)
let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
// let result = UnsafeMutablePointer<CUnsignedChar>.init(allocatingCapacity: digestLen)
CC_MD5(str!, strLen, result)
let hash = NSMutableString()
for i in 0 ..< digestLen {
hash.appendFormat("%02x", result[i])
}
result.deinitialize()
return String(format: hash as String)
}
}
使用方法:
直接在xib界面拖一个textFiled的控件,然后放置3个按钮,分别是进行MD5、sha1、3DES加密点击方法,然后分别测试加密解密数据
//3DES
@IBAction func desButtonClick(_ sender: UIButton) {
let keyStr = "ns@$65ds$%^^vdiefif934I&^%#46gn1a"
print("----原密码---**\(tf.text)**")
/**
3DES的加密过程 和 解密过程
- parameter op : CCOperation: 加密还是解密
CCOperation(kCCEncrypt)加密
CCOperation(kCCDecrypt) 解密
- parameter key: 专有的key,一个钥匙一般
- parameter iv : 可选的初始化向量,可以为nil
- returns : 返回加密或解密的参数
*/
let mi_string = tf.text?.threeDESEncryptOrDecrypt(op: CCOperation(kCCEncrypt), key: keyStr, iv: "")
print("--加密--mi_string----***\(mi_string)**")
let ming_string = mi_string?.threeDESEncryptOrDecrypt(op: CCOperation(kCCDecrypt), key: keyStr, iv: "")
print("--解密--ming_string----***\(ming_string)**")
}
//sha1
@IBAction func sha1ButtonClick(_ sender: UIButton) {
self.view.endEditing(true)
print("---sha1加密---**\(tf.text)")
let psw_sha1 = tf.text?.sha1()
print("---psw_sha1- 加密后的字符串 *****----****\(psw_sha1)")
}
//MD5
@IBAction func MD5ButtonClick(_ sender: UIButton) {
self.view.endEditing(true)
print("---MD5加密---**\(tf.text)")
let psw_MD5 = tf.text?.MD5()
print("---psw_MD5- 加密后的字符串 *****----****\(psw_MD5)")
}
重点问题: 如果遇到3DES解密与java后台的不符合或者解密不成功的情况,可能的原因是需要使用3DES+base64进行加密解密
可以参考文章http://www.cnblogs.com/jukaiit/p/5039803.html
使用这个第三方来实现 JKEncrypt
** https://github.com/jukai9316/JKEncrypt。**
网友评论