前言:
由于app登錄時(shí)缓屠,需要AES128加密,所以在網(wǎng)上查閱資料,自己寫了一個(gè)加密的擴(kuò)展。
以此作為一次學(xué)習(xí)記錄场仲。
導(dǎo)入庫:
首先矛紫,需要導(dǎo)入一個(gè)系統(tǒng)庫:(swift需要寫在橋接文件里)
#import <CommonCrypto/CommonCrypto.h>
基本方法:
CCCryptorStatus CCCrypt(
CCOperation op, /* kCCEncrypt, etc. */
CCAlgorithm alg, /* kCCAlgorithmAES128, etc. */
CCOptions options, /* kCCOptionPKCS7Padding, etc. */
const void *key,
size_t keyLength,
const void *iv, /* optional initialization vector */
const void *dataIn, /* optional per op and alg */
size_t dataInLength,
void *dataOut, /* data RETURNED here */
size_t dataOutAvailable,
size_t *dataOutMoved)
這是加密和解密的一個(gè)基本的方法,其中:
//***操作***//
//opterantion傳值: (CCOperation)
//kCCEncrypt = 0 --> 加密
//kCCDecrypt --> 解密
//***設(shè)置***//
//options傳值: (CCOptions)
//kCCOptionPKCS7Padding = 0x0001 --> 需要iv
//kCCOptionECBMode = 0x0002 --> 不需要iv
//***類型***//
//algorithm傳值: (CCAlgorithm)
//kCCKeySizeAES128 = 16 --> AES128
//kCCKeySizeAES192 = 24 --> AES192
//kCCKeySizeAES256 = 32 --> AES256
//kCCKeySizeDES = 8 --> DES
//kCCKeySize3DES = 24 --> 3DES
//kCCKeySizeMinCAST = 5 --> MIN_CAST
//kCCKeySizeMaxCAST = 16 --> MAX_CAST
//kCCKeySizeMinRC4 = 1 --> MIN_RC4
//kCCKeySizeMaxRC4 = 512 --> MAX_RC4
//kCCKeySizeMinRC2 = 1 --> MIN_RC2
//kCCKeySizeMaxRC2 = 128 --> MAX_RC2
//kCCKeySizeMinBlowfish = 8 --> MIN_BLOWFISH
//kCCKeySizeMaxBlowfish = 56 --> MAX_BLOWFISH
//***其他類型參數(shù)***//
//key:加密密鑰(指針) ------- keyLength:密鑰長度
//dataIn:要加密的數(shù)據(jù)(指針) ------ dataInLength:數(shù)據(jù)的長度
//dataOut:加密后的數(shù)據(jù)(指針) ------ dataOutAvailable:數(shù)據(jù)接收的容器長度
//dataOutMoved:數(shù)據(jù)接收
//*** size_t 和 Int 有區(qū)別:
//size_t是無符號的揍很,并且是平臺(tái)無關(guān)的,表示0-MAXINT的范圍;
//Int 對于 swift 是有符號的
//***const void * 和 void * 都是指針類型矾瘾,分別對應(yīng)swift中UnsafePointer<UInt8>
//和UnsafeMutablePointer<UInt8>女轿,而最新的swift版本中分別對應(yīng)UnsafeRawPointer
//和UnsafeMutableRawPointer
代碼:
Data擴(kuò)展
enum CryptError: Error {
case noIV
case cryptFailed
case notConvertTypeToData
}
extension Data {
///***********加密&解密************///
//===>>>>>>>AES128
func dataCryptAES128(_ options: CCOptions?, _ operation: CCOperation, _ keyData: Data, _ iv: Data?) throws -> Data {
return try self.dataCrypt(options ?? CCOptions(kCCOptionECBMode),
operation,
keyData,
iv,
CCAlgorithm(kCCAlgorithmAES128))
}
//===>>>>>>>基本方法
func dataCrypt(_ options: CCOptions, _ operation: CCOperation, _ keyData: Data, _ iv: Data?, _ algorithm: UInt32) throws -> Data {
if iv == nil && (options & CCOptions(kCCOptionECBMode)) == 0 {
print("Error in crypto operation: dismiss iv!")
throw(CryptError.noIV)
}
//key
let keyBytes = keyData.bytes()
let keyLength = size_t(kCCKeySizeAES128)
//data(input)
let dataBytes = self.bytes()
let dataLength = size_t(self.count)
//data(output)
var buffer = Data(count: dataLength + Int(kCCBlockSizeAES128))
let bufferBytes = buffer.mutableBytes()
let bufferLength = size_t(buffer.count)
//iv
let ivBuffer: UnsafePointer<UInt8>? = iv == nil ? nil : iv!.bytes()
var bytesDecrypted: size_t = 0
let cryptState = CCCrypt(operation,
algorithm,
options,
keyBytes,
keyLength,
ivBuffer,
dataBytes,
dataLength,
bufferBytes,
bufferLength,
&bytesDecrypted)
guard Int32(cryptState) == Int32(kCCSuccess) else {
print("Error in crypto operation: \(cryptState)")
throw(CryptError.cryptFailed)
}
buffer.count = bytesDecrypted
return buffer
}
//===>>>>>>>Help Funcations<<<<<<<===//
func bytes() -> UnsafePointer<UInt8> {
return self.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
return bytes
}
}
mutating func mutableBytes() -> UnsafeMutablePointer<UInt8> {
return self.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> UnsafeMutablePointer<UInt8> in
return bytes
}
}
}
String擴(kuò)展
//AES128加密之后,base64編碼
func aes128AndBase64(_ options: CCOptions?, _ operation: CCOperation, _ keyData: Data, _ iv: Data?) throws -> String {
guard let data = self.data(using: .utf8) else {
throw(CryptError.notConvertTypeToData)
}
let aesData = try data.dataCryptAES128(options,
operation,
keyData,
iv)
return aesData.base64EncodedString()
}
最后附上一個(gè)MD5的加密方法(也是對于String的擴(kuò)展)
//MD5加密
func md5() -> String {
let utf8_str = self.cString(using: .utf8)
let str_len = CC_LONG(self.lengthOfBytes(using: .utf8))
let digest_len = Int(CC_MD5_DIGEST_LENGTH)
let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digest_len)
CC_MD5(utf8_str, str_len, result)
let str = NSMutableString()
for i in 0..<digest_len {
str.appendFormat("%02x", result[i])
}
result.deallocate()
return str as String
}
這只是一次學(xué)習(xí)記錄!:爵妗蛉迹!