AES128加密解密(swift版本)

前言:

 由于app登录时,需要AES128加密,所以在网上查阅资料,自己写了一个加密的扩展。
以此作为一次学习记录。

导入库:

首先,需要导入一个系统库:(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)
这是加密和解密的一个基本的方法,其中:
//***操作***//
//opterantion传值: (CCOperation)
//kCCEncrypt = 0    --> 加密
//kCCDecrypt        --> 解密
//***设置***//
//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
//***其他类型参数***//
//key:加密密钥(指针)  -------  keyLength:密钥长度
//dataIn:要加密的数据(指针)  ------  dataInLength:数据的长度
//dataOut:加密后的数据(指针)  ------  dataOutAvailable:数据接收的容器长度
//dataOutMoved:数据接收
//*** size_t 和 Int 有区别:
//size_t是无符号的,并且是平台无关的,表示0-MAXINT的范围;
//Int 对于 swift 是有符号的
//***const void * 和 void * 都是指针类型,分别对应swift中UnsafePointer<UInt8>
//和UnsafeMutablePointer<UInt8>,而最新的swift版本中分别对应UnsafeRawPointer
//和UnsafeMutableRawPointer

代码:

Data扩展
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扩展
//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()
}

最后附上一个MD5的加密方法(也是对于String的扩展)

//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
}

这只是一次学习记录!!!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,802评论 6 13
  • 之前的项目中接触过一些加密的方法,也没有太仔细的进行记录和研究。最近在写SDK时,加密模块的占比相当之大;借此时机...
    过半_e764阅读 550评论 0 0
  • 本次比赛选手各出奇招,足迹遍布海内外,使出珍藏多年的自拍姿势,只为赢得更多点赞和评论,然而也有部分摄霸已胸有成足,...
    语音灵犀阅读 205评论 0 0
  • 静心品茶是一种乐趣,喝到好茶更是一种美妙的享受。机缘巧合下品到了一款好茶,源自浙江景宁畲族自治县的白玉仙茶。 白玉...
    yaym阅读 1,984评论 0 1
  • 也许和我一样,它也不知道它自己怎么就突然病得那么重。十多天没有吃喝的它坚持到我再次放假回来,然后,第二天我起床,就...
    长留仙山似画人阅读 148评论 0 1