iOS中AES对称加密(CBC模式)实现

前言:

在我们开发中免不了和服务器做一些数据交互,在交互过程中走得都是http请求,这类请求不像https那样的安全所以就会在交互过程中做一些数据加密解密的事情,现在主流的加密是AES对称加密和RSA非对称加密下面给大家讲解下AES加密,非对称加密会过几天跟新。

AES加密介绍:

  • AES加密是一种对称加密方式,他有基本的五种加密模式组成分别是:

1.电码本模式(Electronic Codebook Book (ECB));
2.密码分组链接模式(Cipher Block Chaining (CBC));
3.计算器模式(Counter (CTR));
4.密码反馈模式(Cipher FeedBack (CFB));
5.输出反馈模式(Output FeedBack (OFB))

  • 以上所说的这五种加密模式我们讲最常用的CBC模式,下面我说一下实现AES对称加密(CBC)的基本步骤;

1.要加密的密文转为NSData类型
2.使用AES对称加密(CBC)加密NSData
3.之后对加密过后的NSData进行编码(编码在下面我会说到)

AES加密代码实现:

  • 新建SecurityUtil继承NSObject
SecurityUtil.h实现:
  #pragma mark - AES加密
  //将string转成带密码的data
  + (NSString*)encryptAESData:(NSString*)string Withkey:(NSString * )key ivkey:(NSString * )ivkey;
  //将带密码的data转成string
  +(NSString*)decryptAESData:(NSString*)data Withkey:(NSString *)key ivkey:(NSString * )ivkey;
SecurityUtil.m实现(加密部分):
  #pragma mark - AES加密
  //将string转成带密码的data
  +(NSString*)encryptAESData:(NSString*)string Withkey:(NSString *)key ivkey:(NSString *)ivkey
  {
      //将nsstring转化为nsdata
      NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
      //使用密码对nsdata进行加密
      NSData *encryptedData = [data AES128EncryptWithKey:key ivKey:ivkey];
      //加密之后编码
      return [self dataTohexString:encryptedData];;
  }
  #pragma mark - AES解密
  //将带密码的data转成string
  +(NSString*)decryptAESData:(NSString*)string Withkey:(NSString *)key ivkey:(NSString *)ivkey
  {
      //对数据进行解密
      NSData* result = [[self hexStringToData:string] AES128DecryptWithKey:key ivkey:ivkey];
      if (result && result.length > 0) {
          //加密之后进行编码
          return [[NSString alloc] initWithData:result  encoding:NSUTF8StringEncoding];
      }
         return nil;
  }
SecurityUtil.m实现(编码部分):
  #pragma mark - 16位编码 -加密
  + (NSString *)dataTohexString:(NSData*)data
  {
      Byte *bytes = (Byte *)[data bytes];
      NSString *hexStr=@"";
      for(int i=0;i<[data length];i++)
      {
          NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];//16进制数
          if([newHexStr length]==1)
              hexStr = [NSString        stringWithFormat:@"%@0%@",hexStr,newHexStr];
          else
              hexStr = [NSString       stringWithFormat:@"%@%@",hexStr,newHexStr];
      }
      return hexStr;
  }
  #pragma mark - 16位编码 -解密
  + (NSData*)hexStringToData:(NSString*)hexString
  {
      int j=0;
      Byte bytes[hexString.length];  ///3ds key的Byte 数组, 128位
      for(int i=0;i<[hexString length];i++)
      {
          int int_ch;  /// 两位16进制数转化后的10进制数
          unichar hex_char1 = [hexString characterAtIndex:i]; ////两位16进制数中的第一位(高位*16)
          int int_ch1;
          if(hex_char1 >= '0' && hex_char1 <='9')
          int_ch1 = (hex_char1-48)*16;   //// 0 的Ascll - 48
          else if(hex_char1 >= 'A' && hex_char1 <='F')
              int_ch1 = (hex_char1-55)*16; //// A 的Ascll - 65
          else
              int_ch1 = (hex_char1-87)*16; //// a 的Ascll - 97
          i++;
          unichar hex_char2 = [hexString characterAtIndex:i]; ///两位16进制数中的第二位(低位)
          int int_ch2;
          if(hex_char2 >= '0' && hex_char2 <='9')
              int_ch2 = (hex_char2-48); //// 0 的Ascll - 48
          else if(hex_char1 >= 'A' && hex_char1 <='F')
              int_ch2 = hex_char2-55; //// A 的Ascll - 65
          else
              int_ch2 = hex_char2-87; //// a 的Ascll - 97   
          int_ch = int_ch1+int_ch2;
          //NSLog(@"int_ch=%x",int_ch);
          bytes[j] = int_ch;  ///将转化后的数放入Byte数组里
          j++;
      }
      //    NSData *newData = [[NSData alloc] initWithBytes:bytes length:j];
      NSData *newData = [[NSData alloc] initWithBytes:bytes length:j];
      //NSLog(@"newData=%@",newData);
      return newData;
  }
  • 新建一个NSData的扩展咋们把他命名为AES
NSData+AES.h实现:
  @class NSString;
  @interface NSData (Encryption)
  - (NSData *)AES128EncryptWithKey:(NSString *) key ivKey:(NSString *)ivkey;//加密
  - (NSData *)AES128DecryptWithKey:(NSString *) key ivkey:(NSString * )ivkey;//解密
NSData+AES.m实现:
  //(key和iv向量这里是16位的) 这里是CBC加密模式,安全性更高
  //加密
  - (NSData *)AES128EncryptWithKey:(NSString *) key ivKey:(NSString *)ivkey{
      char keyPtr[kCCKeySizeAES256+1];
      bzero(keyPtr, sizeof(keyPtr));
      [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
      NSUInteger dataLength = [self length];
      size_t bufferSize = dataLength + kCCBlockSizeAES128;
      void *buffer = malloc(bufferSize);
      size_t numBytesEncrypted = 0;
      CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
                                            kCCOptionPKCS7Padding ,
                                            keyPtr, kCCBlockSizeAES128,
                                            [ivkey UTF8String],
                                            [self bytes], dataLength,
                                            buffer, bufferSize,
                                            &numBytesEncrypted);
      if (cryptStatus == kCCSuccess) {
          return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
      }
      free(buffer);
      return nil;
  }
  //解密
  - (NSData *)AES128DecryptWithKey:(NSString *) key ivkey:(NSString *)ivkey {
      char keyPtr[kCCKeySizeAES256+1];
      bzero(keyPtr, sizeof(keyPtr));
      [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
      NSUInteger dataLength = [self length];
      size_t bufferSize = dataLength + kCCBlockSizeAES128;
      void *buffer = malloc(bufferSize);
      size_t numBytesDecrypted = 0;
      CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
                                            kCCOptionPKCS7Padding ,
                                            keyPtr, kCCBlockSizeAES128,
                                            [ivkey UTF8String],
                                            [self bytes], dataLength,
                                            buffer, bufferSize,
                                            &numBytesDecrypted);
      if (cryptStatus == kCCSuccess) {
          return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];        
      }
      free(buffer);
      return nil;
  }
  • 试验调用一下:
    NSString *originalString = @"加密这个字符串";
    NSString * secretStr = @"秘钥是这个";
    //CBC加密字符串
    NSString * encryptCBC = [SecurityUtil  encryptAESData: originalString Withkey:uuid ivkey: secretStr];
    //CBC解密字符串
    NSString * decryptCBC = [SecurityUtil  decryptAESData: encryptCBC Withkey:uuid ivkey: secretStr];
    
  • AES加密(CBC)全部实现我们已经做好了下面我讲一下编码;

    编码有很多种在我的项目中我们采用了16位编码,为什么说我要采用16位编码这又要讲到Base64编码,首先我先给大家看下这俩种编码后的密文是什么样子的。。

Base64编码:

BsDhzys9BkPbfuMUK4SDpSqh47FMMNltY6huj/lMwI77ibB61Wk9eBMMzQRmNgVvmnbTpWKNUdS2XXKgfwuEyGjJC7uUSkoTuV/TFN+BEFv3vlL0UKeY1Jt8plcJzrDKyDxK0oQOiM9THr5ZTFOsdDGfM3cmGWf7KRTQFwYE=

16位编码:

06C0E1CF2B3D0643DB7EE3142B8483A52AA1E3B14C33FA21365B58EA1BA3FE533023BEE26C1EB55A4F5E04C33341198D815BE69DB4E958A354752D975CA81FC2E1321A3242EEE5129284EE57F4C537E04416FDEF94BD1429E63526DF2995C273AC32B20F12B4A103A233D4C7AF965314EB1D0C67CCDDC98659FECA453405C181

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

推荐阅读更多精彩内容