iOS對稱加密(AES與DES)

對稱加密算法:指加密和解密使用相同密鑰的加密算法(包括DES算法,3DES算法,RC5算法,AES算法等)。本文講述AES算法和DES算法,AES和DES都包含兩種加密算法的加密方式分別為ECB和CBC。

AES:高級加密標準,是美國聯(lián)邦政府采用的一種區(qū)塊加密標準。

DES:數(shù)據(jù)加密標準,(現(xiàn)在用的比較少,因為它的加密強度不夠,能夠暴力破解)。

ECB:電子密碼本,就是每個塊都是獨立加密的。

CBC:密碼塊鏈,使用一個密鑰和一個初始化向量(IV)對數(shù)據(jù)執(zhí)行加密轉換。

EncryptionTools.h 文件代碼如下:

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCrypto.h>
@interface EncryptionTools : NSObject

/**
 *  AES加密
 *
 *  @param string    要加密的字符串
 *  @param keyString 加密密鑰
 *  @param iv        初始化向量(8個字節(jié))
 *
 *  @return 返回加密后的base64編碼字符串
 */
+ (NSString *)aesEncryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;

/**
 *  AES解密
 *
 *  @param string    加密并base64編碼后的字符串
 *  @param keyString 解密密鑰
 *  @param iv        初始化向量(8個字節(jié))
 *
 *  @return 返回解密后的字符串
 */
+ (NSString *)aesDecryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;

/**
 *  DES加密
 *
 *  @param string    要加密的字符串
 *  @param keyString 加密密鑰
 *  @param iv        初始化向量(8個字節(jié))
 *
 *  @return 返回加密后的base64編碼字符串
 */
+ (NSString *)desEncryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;

/**
 *  DES解密
 *
 *  @param string    加密并base64編碼后的字符串
 *  @param keyString 解密密鑰
 *  @param iv        初始化向量(8個字節(jié))
 *
 *  @return 返回解密后的字符串
 */
+ (NSString *)desDecryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;

@end

EncryptionTools.m 文件代碼如下:


#import "EncryptionTools.h"

@implementation EncryptionTools

//AES加密
+ (NSString *)aesEncryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
   // 設置秘鑰
   NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
   uint8_t cKey[kCCKeySizeAES128];
   bzero(cKey, sizeof(cKey));
   [keyData getBytes:cKey length:kCCKeySizeAES128];
   
   // 設置iv
   uint8_t cIv[kCCBlockSizeAES128];
   bzero(cIv, kCCBlockSizeAES128);
   int option = 0;
   if (iv) {
       [iv getBytes:cIv length:kCCBlockSizeAES128];
       option = kCCOptionPKCS7Padding;
   } else {
       option = kCCOptionPKCS7Padding | kCCOptionECBMode;
   }
   
   // 設置輸出緩沖區(qū)
   NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
   size_t bufferSize = [data length] + kCCBlockSizeAES128;
   void *buffer = malloc(bufferSize);
   
   // 開始加密
   size_t encryptedSize = 0;
   
   /**
    @constant   kCCAlgorithmAES     高級加密標準,128位(默認)
    @constant   kCCAlgorithmDES     數(shù)據(jù)加密標準
    */
   CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                         kCCAlgorithmAES,
                                         option,
                                         cKey,
                                         kCCKeySizeAES128,
                                         cIv,
                                         [data bytes],
                                         [data length],
                                         buffer,
                                         bufferSize,
                                         &encryptedSize);
   
   NSData *result = nil;
   if (cryptStatus == kCCSuccess) {
       result = [NSData dataWithBytesNoCopy:buffer length:encryptedSize];
   } else {
       free(buffer);
       NSLog(@"[錯誤] 加密失敗|狀態(tài)編碼: %d", cryptStatus);
   }
   
   return [result base64EncodedStringWithOptions:0];
}

//AES解密
+ (NSString *)aesDecryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
   // 設置秘鑰
   NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
   uint8_t cKey[kCCKeySizeAES128];
   bzero(cKey, sizeof(cKey));
   [keyData getBytes:cKey length:kCCKeySizeAES128];
   
   // 設置iv
   uint8_t cIv[kCCBlockSizeAES128];
   bzero(cIv, kCCBlockSizeAES128);
   int option = 0;
   if (iv) {
       [iv getBytes:cIv length:kCCBlockSizeAES128];
       option = kCCOptionPKCS7Padding;
   } else {
       option = kCCOptionPKCS7Padding | kCCOptionECBMode;
   }
   
   // 設置輸出緩沖區(qū),options參數(shù)很多地方是直接寫0,但是在實際過程中可能出現(xiàn)回車的字符串導致解不出來
   NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:NSDataBase64DecodingIgnoreUnknownCharacters];
   
   size_t bufferSize = [data length] + kCCBlockSizeAES128;
   void *buffer = malloc(bufferSize);
   
   // 開始解密
   size_t decryptedSize = 0;
   CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                         kCCAlgorithmAES128,
                                         option,
                                         cKey,
                                         kCCKeySizeAES128,
                                         cIv,
                                         [data bytes],
                                         [data length],
                                         buffer,
                                         bufferSize,
                                         &decryptedSize);
   
   NSData *result = nil;
   if (cryptStatus == kCCSuccess) {
       result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
   } else {
       free(buffer);
       NSLog(@"[錯誤] 解密失敗|狀態(tài)編碼: %d", cryptStatus);
   }
   
   return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
}

//DES加密
+ (NSString *)desEncryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
   // 設置秘鑰
   NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
   uint8_t cKey[kCCKeySizeDES];
   bzero(cKey, sizeof(cKey));
   [keyData getBytes:cKey length:kCCKeySizeDES];
   
   // 設置iv
   uint8_t cIv[kCCBlockSizeDES];
   bzero(cIv, kCCBlockSizeDES);
   int option = 0;
   if (iv) {
       [iv getBytes:cIv length:kCCBlockSizeDES];
       option = kCCOptionPKCS7Padding;
   } else {
       option = kCCOptionPKCS7Padding | kCCOptionECBMode;
   }
   
   // 設置輸出緩沖區(qū)
   NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
   size_t bufferSize = [data length] + kCCBlockSizeDES;
   void *buffer = malloc(bufferSize);
   
   // 開始加密
   size_t encryptedSize = 0;
   
   CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                         kCCAlgorithmDES,
                                         option,
                                         cKey,
                                         kCCKeySizeDES,
                                         cIv,
                                         [data bytes],
                                         [data length],
                                         buffer,
                                         bufferSize,
                                         &encryptedSize);
   
   NSData *result = nil;
   if (cryptStatus == kCCSuccess) {
       result = [NSData dataWithBytesNoCopy:buffer length:encryptedSize];
   } else {
       free(buffer);
       NSLog(@"[錯誤] 加密失敗|狀態(tài)編碼: %d", cryptStatus);
   }
   
   return [result base64EncodedStringWithOptions:0];
}

//DES解密
+ (NSString *)desDecryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
   // 設置秘鑰
   NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
   uint8_t cKey[kCCKeySizeDES];
   bzero(cKey, sizeof(cKey));
   [keyData getBytes:cKey length:kCCKeySizeDES];
   
   // 設置iv
   uint8_t cIv[kCCBlockSizeDES];
   bzero(cIv, kCCBlockSizeDES);
   int option = 0;
   if (iv) {
       [iv getBytes:cIv length:kCCBlockSizeDES];
       option = kCCOptionPKCS7Padding;
   } else {
       option = kCCOptionPKCS7Padding | kCCOptionECBMode;
   }
   
   // 設置輸出緩沖區(qū),options參數(shù)很多地方是直接寫0,但是在實際過程中可能出現(xiàn)回車的字符串導致解不出來
   NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:NSDataBase64DecodingIgnoreUnknownCharacters];

   size_t bufferSize = [data length] + kCCBlockSizeDES;
   void *buffer = malloc(bufferSize);
   
   // 開始解密
   size_t decryptedSize = 0;
   CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                         kCCAlgorithmDES,
                                         option,
                                         cKey,
                                         kCCKeySizeDES,
                                         cIv,
                                         [data bytes],
                                         [data length],
                                         buffer,
                                         bufferSize,
                                         &decryptedSize);
   
   NSData *result = nil;
   if (cryptStatus == kCCSuccess) {
       result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
   } else {
       free(buffer);
       NSLog(@"[錯誤] 解密失敗|狀態(tài)編碼: %d", cryptStatus);
   }
   
   return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
}

@end

ViewController.m 文件調用

#import "ViewController.h"
#import "EncryptionTools.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    //iv向量
    NSString *iv = @"abcdefghijklmnop";
    //轉化為data,在java中是一個byte類型
    NSData *ivData = [iv dataUsingEncoding:NSUTF8StringEncoding];
    
    /****************************AES********************************/
    //aes-ecb加密, iv直接傳nil就行
    NSString *aesEcbE = [EncryptionTools aesEncryptString:@"這個是AES-ECB加密" keyString:@"abcdefghi1234567" iv:nil];
    NSLog(@"aes-ecb加密: %@", aesEcbE);
    
    //aes-ecb解密, iv直接傳nil就行
    NSString *aesEcbD = [EncryptionTools aesDecryptString:@"BKsrfQeUQnMEbPUxcbcy79Xuq4t2i04MgoFRDB8p7CI=" keyString:@"abcdefghi1234567" iv:nil];
    NSLog(@"aes-ecb解密: %@", aesEcbD);
    
    //aes-cbc加密
    NSString *aesCbcE = [EncryptionTools aesEncryptString:@"這個是AES-CBC加密" keyString:@"abcdefghi1234567" iv:ivData];
    NSLog(@"aes-cbc加密: %@", aesCbcE);
    
    //aes-cbc解密
    NSString *aesCbcD = [EncryptionTools aesDecryptString:@"eo9dQHISb7Uh6H7iYjPa5PyxaBfU1oFKdJiwJsqXIsg=" keyString:@"abcdefghi1234567" iv:ivData];
    NSLog(@"aes-cbc解密: %@", aesCbcD);
    
    /****************************DES********************************/
    
    //aes-ecb加密, iv直接傳nil就行
    NSString *desEcbE = [EncryptionTools desEncryptString:@"這個是DES-ECB加密" keyString:@"abcdefghi1234567" iv:nil];
    NSLog(@"des-ecb加密: %@", desEcbE);
    
    //aes-ecb解密, iv直接傳nil就行
    NSString *desEcbD = [EncryptionTools desDecryptString:@"fu2IYaT9ovofPt1trAt5nsgyPf16zJYB" keyString:@"abcdefghi1234567" iv:nil];
    NSLog(@"des-ecb解密: %@", desEcbD);
    
    //aes-cbc加密
    NSString *desCbcE = [EncryptionTools desEncryptString:@"這個是DES-ECB加密" keyString:@"abcdefghi1234567" iv:ivData];
    NSLog(@"des-cbc加密: %@", desCbcE);
    
    //aes-cbc解密
    NSString *desCbcD = [EncryptionTools desDecryptString:@"qqeY0KWFB6WikoZgtmiy9nrB8SLjsv90" keyString:@"abcdefghi1234567" iv:ivData];
    NSLog(@"des-cbc解密: %@", desCbcD);
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

打印結果如下:

Paste_Image.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 本文主要介紹移動端的加解密算法的分類、其優(yōu)缺點特性及應用,幫助讀者由淺入深地了解和選擇加解密算法。文中會包含算法的...
    蘋果粉閱讀 11,674評論 5 29
  • 對稱加密 - 傳統(tǒng)加密算法##加密和解密使用同一個"密鑰"!密鑰的保密工作就非常的重要!! 密鑰會定期更換!密鑰的...
    Maple_Xu閱讀 1,367評論 0 3
  • 版本記錄 前言 在這個信息爆炸的年代,特別是一些敏感的行業(yè),比如金融業(yè)和銀行卡相關等等,這都對app的安全機制有更...
    刀客傳奇閱讀 1,553評論 0 3
  • 概述 之前一直對加密相關的算法知之甚少,只知道類似DES、RSA等加密算法能對數(shù)據(jù)傳輸進行加密,且各種加密算法各有...
    Henryzhu閱讀 3,208評論 0 14
  • 我想,我們這一生都在不斷地經歷著告別。 小時的我們還不懂什么是告別,也不懂告別對于我們的生活而言意味著什么。只是隱...
    皮皮昕閱讀 366評論 0 5

友情鏈接更多精彩內容