AES128加密解密(swift版本)

前言:

 由于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í)記錄!:爵妗蛉迹!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市放妈,隨后出現(xiàn)的幾起案子北救,更是在濱河造成了極大的恐慌,老刑警劉巖芜抒,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件珍策,死亡現(xiàn)場離奇詭異,居然都是意外死亡宅倒,警方通過查閱死者的電腦和手機(jī)攘宙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拐迁,“玉大人蹭劈,你說我怎么就攤上這事∠哒伲” “怎么了铺韧?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長缓淹。 經(jīng)常有香客問我哈打,道長,這世上最難降的妖魔是什么讯壶? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任料仗,我火速辦了婚禮,結(jié)果婚禮上鹏溯,老公的妹妹穿的比我還像新娘罢维。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布肺孵。 她就那樣靜靜地躺著匀借,像睡著了一般。 火紅的嫁衣襯著肌膚如雪平窘。 梳的紋絲不亂的頭發(fā)上吓肋,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天,我揣著相機(jī)與錄音瑰艘,去河邊找鬼是鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛紫新,可吹牛的內(nèi)容都是我干的均蜜。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼芒率,長吁一口氣:“原來是場噩夢啊……” “哼囤耳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起偶芍,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤充择,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后匪蟀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體椎麦,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年材彪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了观挎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,769評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡段化,死狀恐怖键兜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情穗泵,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布谜疤,位于F島的核電站佃延,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏夷磕。R本人自食惡果不足惜履肃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坐桩。 院中可真熱鬧尺棋,春花似錦、人聲如沸绵跷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至荆残,卻和暖如春奴艾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背内斯。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工蕴潦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人俘闯。 一個(gè)月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓潭苞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親真朗。 傳聞我的和親對象是個(gè)殘疾皇子此疹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 11,009評論 6 13
  • 之前的項(xiàng)目中接觸過一些加密的方法,也沒有太仔細(xì)的進(jìn)行記錄和研究蜜猾。最近在寫SDK時(shí)秀菱,加密模塊的占比相當(dāng)之大;借此時(shí)機(jī)...
    過半_e764閱讀 577評論 0 0
  • 本次比賽選手各出奇招,足跡遍布海內(nèi)外肩豁,使出珍藏多年的自拍姿勢脊串,只為贏得更多點(diǎn)贊和評論,然而也有部分?jǐn)z霸已胸有成足清钥,...
    語音靈犀閱讀 221評論 0 0
  • 靜心品茶是一種樂趣琼锋,喝到好茶更是一種美妙的享受。機(jī)緣巧合下品到了一款好茶祟昭,源自浙江景寧畬族自治縣的白玉仙茶缕坎。 白玉...
    yaym閱讀 2,028評論 0 1
  • 也許和我一樣,它也不知道它自己怎么就突然病得那么重篡悟。十多天沒有吃喝的它堅(jiān)持到我再次放假回來谜叹,然后,第二天我起床搬葬,就...
    長留仙山似畫人閱讀 154評論 0 1