514 iOS中AES對稱加密(CBC模式)實現(xiàn)(面試點:對稱加密常用的AES 算法CBC模式亭螟。非對稱加密:RSA加密算法)

前言:

在我們開發(fā)中免不了和服務器做一些數(shù)據(jù)交互,在交互過程中走得都是http請求骑歹,這類請求不像https那樣的安全所以就會在交互過程中做一些數(shù)據(jù)加密解密的事情预烙,現(xiàn)在主流的加密是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模式镀脂,下面我說一下實現(xiàn)AES對稱加密(CBC)的基本步驟;

1.要加密的密文轉(zhuǎn)為NSData類型
2.使用AES對稱加密(CBC)加密NSData
3.之后對加密過后的NSData進行編碼(編碼在下面我會說到)

AES加密代碼實現(xiàn):

新建SecurityUtil繼承NSObject
SecurityUtil.h實現(xiàn):

  #pragma mark - AES加密
  //將string轉(zhuǎn)成帶密碼的data
  + (NSString*)encryptAESData:(NSString*)string Withkey:(NSString * )key ivkey:(NSString * )ivkey;
  //將帶密碼的data轉(zhuǎn)成string
  +(NSString*)decryptAESData:(NSString*)data Withkey:(NSString *)key ivkey:(NSString * )ivkey;

SecurityUtil.m實現(xiàn)(加密部分):

  #pragma mark - AES加密
  //將string轉(zhuǎn)成帶密碼的data
  +(NSString*)encryptAESData:(NSString*)string Withkey:(NSString *)key ivkey:(NSString *)ivkey
  {
      //將nsstring轉(zhuǎn)化為nsdata
      NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
      //使用密碼對nsdata進行加密
      NSData *encryptedData = [data AES128EncryptWithKey:key ivKey:ivkey];
      //加密之后編碼
      return [self dataTohexString:encryptedData];;
  }
  #pragma mark - AES解密
  //將帶密碼的data轉(zhuǎn)成string
  +(NSString*)decryptAESData:(NSString*)string Withkey:(NSString *)key ivkey:(NSString *)ivkey
  {
      //對數(shù)據(jù)進行解密
      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實現(xiàn)(編碼部分):

  #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進制數(shù)
          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 數(shù)組牺蹄, 128位
      for(int i=0;i<[hexString length];i++)
      {
          int int_ch;  /// 兩位16進制數(shù)轉(zhuǎn)化后的10進制數(shù)
          unichar hex_char1 = [hexString characterAtIndex:i]; ////兩位16進制數(shù)中的第一位(高位*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進制數(shù)中的第二位(低位)
          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;  ///將轉(zhuǎn)化后的數(shù)放入Byte數(shù)組里
          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實現(xiàn):

  @class NSString;
  @interface NSData (Encryption)
  - (NSData *)AES128EncryptWithKey:(NSString *) key ivKey:(NSString *)ivkey;//加密
  - (NSData *)AES128DecryptWithKey:(NSString *) key ivkey:(NSString * )ivkey;//解密

NSData+AES.m實現(xiàn):

  //(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;
  }
  • 試驗調(diào)用一下:
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)全部實現(xiàn)我們已經(jīng)做好了下面我講一下編碼;
    編碼有很多種在我的項目中我們采用了16位編碼薄翅,為什么說我要采用16位編碼這又要講到Base64編碼沙兰,首先我先給大家看下這倆種編碼后的密文是什么樣子的氓奈。。

Base64編碼:

BsDhzys9BkPbfuMUK4SDpSqh47FMMNltY6huj/lMwI77ibB61Wk9eBMMzQRmNgVvmnbTpWKNUdS2XXKgfwuEyGjJC7uUSkoTuV/TFN+BEFv3vlL0UKeY1Jt8plcJzrDKyDxK0oQOiM9THr5ZTFOsdDGfM3cmGWf7KRTQFwYE=

16位編碼:
06C0E1CF2B3D0643DB7EE3142B8483A52AA1E3B14C33FA21365B58EA1BA3FE533023BEE26C1EB55A4F5E04C33341198D815BE69DB4E958A354752D975CA81FC2E1321A3242EEE5129284EE57F4C537E04416FDEF94BD1429E63526DF2995C273AC32B20F12B4A103A233D4C7AF965314EB1D0C67CCDDC98659FECA453405C181

大家也看到了倆種編碼之后的密文明顯的不同之處鼎天,Base64的唯一缺點就是其中有很多的特殊符號這種特殊符號在http傳送過程中會發(fā)生改變導致密文解碼解不了舀奶,所以我就采用了16位編碼避免這種事情的發(fā)生。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斋射,一起剝皮案震驚了整個濱河市育勺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌罗岖,老刑警劉巖涧至,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異呀闻,居然都是意外死亡化借,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門捡多,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蓖康,“玉大人,你說我怎么就攤上這事垒手∷夂福” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵科贬,是天一觀的道長泳梆。 經(jīng)常有香客問我,道長榜掌,這世上最難降的妖魔是什么优妙? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮憎账,結(jié)果婚禮上套硼,老公的妹妹穿的比我還像新娘。我一直安慰自己胞皱,他們只是感情好邪意,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著反砌,像睡著了一般雾鬼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宴树,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天策菜,我揣著相機與錄音,去河邊找鬼。 笑死做入,一個胖子當著我的面吹牛冒晰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播竟块,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼壶运,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了浪秘?” 一聲冷哼從身側(cè)響起蒋情,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎耸携,沒想到半個月后棵癣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡夺衍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年狈谊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沟沙。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡河劝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出矛紫,到底是詐尸還是另有隱情赎瞎,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布颊咬,位于F島的核電站务甥,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏喳篇。R本人自食惡果不足惜敞临,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望麸澜。 院中可真熱鬧哟绊,春花似錦、人聲如沸痰憎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铣耘。三九已至,卻和暖如春以故,著一層夾襖步出監(jiān)牢的瞬間蜗细,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留炉媒,地道東北人踪区。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像吊骤,于是被迫代替她去往敵國和親缎岗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

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