對于字符串的加密解密,可以給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 : 返回加密或解密的參數(shù)
*/
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)
// 返回數(shù)據(jù)
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)
// 特定的幾個參數(shù)
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, // 秘鑰的字節(jié)
keyLength, // 秘鑰的長度
viDataBytes, // 可選初始化向量的字節(jié)
dataBytes, // 加解密內容的字節(jié)
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數(shù)據(jù)格式可能有問題,最好不用
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加密點擊方法,然后分別測試加密解密數(shù)據(jù)
//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 : 返回加密或解密的參數(shù)
*/
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
使用這個第三方來實現(xiàn) JKEncrypt
** https://github.com/jukai9316/JKEncrypt。**