對稱加密工具類

源文件

頭文件

包含終端命令,可以驗證加密結(jié)果是否正確


#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCrypto.h>

/**
 *  終端測試指令
 * 其中 -k 是key的ascii碼
 * 可以利用
 *  DES(ECB)加密
 *  $ echo -n hello | openssl enc -des-ecb -K 616263 -nosalt | base64
 *
  * DES(CBC)加密
 *  $ echo -n hello | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
 *
 *  AES(ECB)加密
 *  $ echo -n hello | openssl enc -aes-128-ecb -K 616263 -nosalt | base64
 *
 *  AES(CBC)加密
 *  $ echo -n hello | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
 *
 *  DES(ECB)解密
 *  $ echo -n HQr0Oij2kbo= | base64 -D | openssl enc -des-ecb -K 616263 -nosalt -d
 *
 *  DES(CBC)解密
 *  $ echo -n alvrvb3Gz88= | base64 -D | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -d
 *
 *  AES(ECB)解密
 *  $ echo -n d1QG4T2tivoi0Kiu3NEmZQ== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d
 *
 *  AES(CBC)解密
 *  $ echo -n u3W/N816uzFpcg6pZ+kbdg== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d
 *
 *  提示:
 *      1> 加密過程是先加密,再base64編碼
 *      2> 解密過程是先base64解碼,再解密
 */
@interface EncryptionTools : NSObject

+ (instancetype)sharedEncryptionTools;

/**
 @constant   kCCAlgorithmAES     高級加密標準,128位(默認)
 @constant   kCCAlgorithmDES     數(shù)據(jù)加密標準
 */
@property (nonatomic, assign) uint32_t algorithm;

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

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

@end

體文件


#import "EncryptionTools.h"

@interface EncryptionTools()
@property (nonatomic, assign) int keySize;
@property (nonatomic, assign) int blockSize;
@end

@implementation EncryptionTools

+ (instancetype)sharedEncryptionTools {
    static EncryptionTools *instance;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
        instance.algorithm = kCCAlgorithmAES;
    });
    
    return instance;
}

- (void)setAlgorithm:(uint32_t)algorithm {
    _algorithm = algorithm;
    switch (algorithm) {
        case kCCAlgorithmAES:
            self.keySize = kCCKeySizeAES128;
            self.blockSize = kCCBlockSizeAES128;
            break;
        case kCCAlgorithmDES:
            self.keySize = kCCKeySizeDES;
            self.blockSize = kCCBlockSizeDES;
            break;
        default:
            break;
    }
}

- (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
    
    // 設(shè)置秘鑰
    NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t cKey[self.keySize];
    bzero(cKey, sizeof(cKey));
    [keyData getBytes:cKey length:self.keySize];
    
    // 設(shè)置iv
    uint8_t cIv[self.blockSize];
    bzero(cIv, self.blockSize);
    int option = 0;
    if (iv) {
        [iv getBytes:cIv length:self.blockSize];
        option = kCCOptionPKCS7Padding;
    } else {
        option = kCCOptionPKCS7Padding | kCCOptionECBMode;
    }
    
    // 設(shè)置輸出緩沖區(qū)
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    size_t bufferSize = [data length] + self.blockSize;
    void *buffer = malloc(bufferSize);
    
    // 開始加密
    size_t encryptedSize = 0;
    /*
     CCCrypt:對稱加密的核心函數(shù)(加密、解密)
     參數(shù):
     1:加密kCCEncrypt、解密kCCDecrypt
     2:加密算法 AES/DES 
     kCCAlgorithmAES     高級加密標準
     kCCAlgorithmDES     數(shù)據(jù)加密標準
     
     3.加密選項:ECB/CBC
     4.加密的密鑰 
     5.密鑰長度
     6.iv 初始化向量
     7.加密的長度
     8.加密的數(shù)據(jù)長度
     9.密文的內(nèi)存地址
     10.密文緩沖區(qū)大小
     11.加密結(jié)果大小
     */
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          self.algorithm,
                                          option,
                                          cKey,
                                          self.keySize,
                                          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];
}

- (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
    
    // 設(shè)置秘鑰
    NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t cKey[self.keySize];
    bzero(cKey, sizeof(cKey));
    [keyData getBytes:cKey length:self.keySize];
    
    // 設(shè)置iv
    uint8_t cIv[self.blockSize];
    bzero(cIv, self.blockSize);
    int option = 0;
    if (iv) {
        [iv getBytes:cIv length:self.blockSize];
        option = kCCOptionPKCS7Padding;
    } else {
        option = kCCOptionPKCS7Padding | kCCOptionECBMode;
    }
    
    // 設(shè)置輸出緩沖區(qū)
    NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:0];
    size_t bufferSize = [data length] + self.blockSize;
    void *buffer = malloc(bufferSize);
    
    // 開始解密
    size_t decryptedSize = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          self.algorithm,
                                          option,
                                          cKey,
                                          self.keySize,
                                          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

使用方法

AES - ECB 加密

每個加密塊是一個獨立的單元,當拆分后再拼接 不影響其他的加密單元

 //AES - ECB 加密
    NSString *key = @"LYJ";
    
    //iv 不需要向量
   //加密
   NSString *reslut =  [[EncryptionTools sharedEncryptionTools]encryptString:@"hello" keyString:key iv:nil];
     NSLog(@"加密結(jié)果:%@",reslut);
    
   //解密
    NSString *decryptString = [[EncryptionTools sharedEncryptionTools]decryptString:reslut keyString:key iv:nil];
    NSLog(@"解密結(jié)果:%@",decryptString);
    

//AES - CBC

加密單元不是獨立,后面的加密依賴前面單元數(shù)據(jù)的加密,更加安全需要向量

 //AES - CBC
    uint8_t iv[8] = {1,2,3,4,5,6,7,8};
    NSData *ivData = [NSData dataWithBytes:iv length:sizeof(iv)];
    
    NSString *CBC_EncryptString = [[EncryptionTools sharedEncryptionTools]encryptString:@"liyanjun" keyString:key iv:ivData];
    
    NSLog(@"CBC加密字符串 %@",CBC_EncryptString);
    
    
    NSString *CBC_DecryptString = [[EncryptionTools sharedEncryptionTools]decryptString:CBC_EncryptString keyString:key iv:ivData];
    
    
    NSLog(@"CBC解密字符串 %@",CBC_DecryptString);

des 給工具類單例的一個參數(shù)設(shè)置一下值即可

 //DES - ECB
    [EncryptionTools sharedEncryptionTools].algorithm = kCCAlgorithmDES;
     NSString *DES_ECB_EncryptString =  [[EncryptionTools sharedEncryptionTools]encryptString:@"hello" keyString:key iv:nil];

    NSLog(@"DES_ECB加密字符串 %@",DES_ECB_EncryptString);

    NSString *ECB_CBC_DecryptString = [[EncryptionTools sharedEncryptionTools]decryptString:DES_ECB_EncryptString keyString:key iv:nil];
    NSLog(@"DES_ECB解密字符串 %@",ECB_CBC_DecryptString);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 對稱加密 - 傳統(tǒng)加密算法##加密和解密使用同一個"密鑰"!密鑰的保密工作就非常的重要!! 密鑰會定期更換!密鑰的...
    Maple_Xu閱讀 1,369評論 0 3
  • 1、簡介對稱加密算法又稱傳統(tǒng)加密算法。加密和解密使用同一個 密鑰。 1.1對稱加密算法示例密鑰:X加密算法:每個字...
    6ffd6634d577閱讀 3,101評論 0 2
  • 對稱加密一 基本介紹1、簡介? 對稱加密算法又稱傳統(tǒng)加密算法。? 加密和解密使用同一個 密鑰。2、對稱加密算法示例...
    第1001號群眾演員閱讀 544評論 0 0
  • 版本記錄 前言 在這個信息爆炸的年代,特別是一些敏感的行業(yè),比如金融業(yè)和銀行卡相關(guān)等等,這都對app的安全機制有更...
    刀客傳奇閱讀 1,554評論 0 3

友情鏈接更多精彩內(nèi)容