iOS對(duì)稱加密

  • 對(duì)稱加密 - 傳統(tǒng)加密算法##

    • 加密和解密使用同一個(gè)"密鑰"!
    • 密鑰的保密工作就非常的重要!! 密鑰會(huì)定期更換!密鑰的管理很重要!!
  • 經(jīng)典算法
    • DES 數(shù)據(jù)加密標(biāo)準(zhǔn)(用的比較少,因?yàn)閺?qiáng)度不夠).
    • 3DES 使用3個(gè)密鑰,對(duì)相同的數(shù)據(jù)執(zhí)行三次加密,強(qiáng)度增強(qiáng).
    • AES 高級(jí)加密標(biāo)準(zhǔn),也是目前使用最多的對(duì)稱加密算法,目前美國(guó)國(guó)家安全局使用AES加密,蘋果的鑰匙串訪問就是使用AES加密
  • 兩種加密方式 (ECB和CBC)
    • ECB: 電子代碼本,就是將一個(gè)數(shù)據(jù)拆分為多塊,然后獨(dú)立加密的!
    • CBC: 密碼塊鏈,使用一個(gè)密鑰和一個(gè)初始化"向量"對(duì)數(shù)據(jù)執(zhí)行加密轉(zhuǎn)換滥搭,能保證密文的完整性,如果一個(gè)數(shù)據(jù)發(fā)生改變,后面所有的數(shù)據(jù)將會(huì)被破壞!
      向量:某個(gè)方向的數(shù)量.
      現(xiàn)代的密碼學(xué)都和幾何有關(guān)!因?yàn)閹缀?包含圓形\橢圓\球體)的變量是有規(guī)律的,但是結(jié)果是多變的!
  • 終端測(cè)試
    接下來(lái)我們分別使用 DES和AES兩種算法的兩種加密方式來(lái)終端測(cè)試一下艾猜。
/**
 *  終端測(cè)試指令
 *
 *  DES(ECB)加密
 *  $ echo -n 加密的內(nèi)容如:(hello) | openssl enc -des-ecb -K Key的ASCII碼如:(abc=616263) -nosalt | base64
 *
 * DES(CBC)加密
 *  $ echo -n 加密的內(nèi)容如:(hello) | openssl enc -des-cbc -iv 初始化向量(8個(gè)字節(jié))如:0102030405060708 -K Key的ASCII碼如:(abc=616263) -nosalt | base64
 *
 *  AES(ECB)加密
 *  $ echo -n 加密的內(nèi)容如:(hello) | openssl enc -aes-128-ecb -K Key的ASCII碼如:(abc=616263) -nosalt | base64
 *
 *  AES(CBC)加密
 *  $ echo -n 加密的內(nèi)容如:(hello) | openssl enc -aes-128-cbc -iv 初始化向量(8個(gè)字節(jié))如:0102030405060708 -K Key的ASCII碼如:(abc=616263) -nosalt | base64
 *
 *  DES(ECB)解密
 *  $ echo -n 解密的內(nèi)容如:(HQr0Oij2kbo=) | base64 -D | openssl enc -des-ecb -K Key的ASCII碼如:(abc=616263) -nosalt -d
 *
 *  DES(CBC)解密
 *  $ echo -n 解密的內(nèi)容如:(alvrvb3Gz88=) | base64 -D | openssl enc -des-cbc -iv 初始化向量(8個(gè)字節(jié))如:0102030405060708 -K Key的ASCII碼如:(abc=616263) -nosalt -d
 *
 *  AES(ECB)解密
 *  $ echo -n 解密的內(nèi)容如:(d1QG4T2tivoi0Kiu3NEmZQ==) | base64 -D | openssl enc -aes-128-ecb -K Key的ASCII碼如:(abc=616263) -nosalt -d
 *
 *  AES(CBC)解密
 *  $ echo -n 解密的內(nèi)容如:(u3W/N816uzFpcg6pZ+kbdg==) | base64 -D | openssl enc -aes-128-cbc -iv 初始化向量(8個(gè)字節(jié))如:0102030405060708 -K Key的ASCII碼如:(abc=616263) -nosalt -d
 *
 *  提示:
 *      1> 加密過程是先加密拷肌,再base64編碼
 *      2> 解密過程是先base64解碼黔攒,再解密
 */
  • OC中具體的代碼實(shí)現(xiàn)
    首先新建一個(gè)工具類 (EncryptionTools)

    EncryptionTools.h


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

@interface EncryptionTools : NSObject

+ (instancetype)sharedEncryptionTools;

/**
 @constant   kCCAlgorithmAES     高級(jí)加密標(biāo)準(zhǔn),128位(默認(rèn))
 @constant   kCCAlgorithmDES     數(shù)據(jù)加密標(biāo)準(zhǔn)
 */
@property (nonatomic, assign) uint32_t algorithm;

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

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

@end

EncryptionTools.m


#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
    /*
     kCCOptionPKCS7Padding                      CBC 的加密方式
     kCCOptionPKCS7Padding | kCCOptionECBMode   ECB 的加密方式
     */
    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 對(duì)稱加密算法的核心函數(shù)(加密/解密)
     參數(shù):
     1.kCCEncrypt  加密/kCCDecrypt 解密
     2.加密算法,默認(rèn)使用的是  AES/DES
     3.加密選項(xiàng)  ECB/CBC 
         kCCOptionPKCS7Padding                      CBC 的加密方式
         kCCOptionPKCS7Padding | kCCOptionECBMode   ECB 的加密方式
     4.加密密鑰
     5.密鑰長(zhǎng)度
     6.iv 初始化向量,ECB 不需要指定
     7.加密的數(shù)據(jù)
     8.加密的數(shù)據(jù)的長(zhǎng)度
     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(@"[錯(cuò)誤] 加密失敗|狀態(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(@"[錯(cuò)誤] 解密失敗|狀態(tài)編碼: %d", cryptStatus);
    }
    
    return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
}

@end

使用工具類加密和解密

    //AES - ECB 加密
    NSString * key = @"hk";
    NSLog(@"加密: %@",[[EncryptionTools sharedEncryptionTools] encryptString:@"hello" keyString:key iv:nil]);
    NSLog(@"解密: %@",[[EncryptionTools sharedEncryptionTools] decryptString:@"cKRPM1ALLG+0q5qCjADoaQ==" keyString:key iv:nil]);
    
    
    
    //AES - CBC 加密
    uint8_t iv[8] = {2,3,4,5,6,7,0,0}; //直接影響加密結(jié)果!
    NSData * ivData = [NSData dataWithBytes:iv length:sizeof(iv)];
    NSLog(@"CBC加密: %@",[[EncryptionTools sharedEncryptionTools] encryptString:@"hello" keyString:key iv:ivData]);
    NSLog(@"CBC解密: %@", [[EncryptionTools sharedEncryptionTools] decryptString:@"+dv/u4juE0WE3S9XSFyibA==" keyString:key iv:ivData]);
    
    //DES - ECB 加密
    [EncryptionTools sharedEncryptionTools].algorithm = kCCAlgorithmDES;
    NSLog(@"DES 加密%@",[[EncryptionTools sharedEncryptionTools] encryptString:@"hello" keyString:key iv:nil]);
    NSLog(@"DES 解密: %@", [[EncryptionTools sharedEncryptionTools] decryptString:@"vTuv8E5AlWQ=" keyString:key iv:nil]);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末舶斧,一起剝皮案震驚了整個(gè)濱河市欣鳖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌茴厉,老刑警劉巖泽台,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異矾缓,居然都是意外死亡怀酷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門嗜闻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蜕依,“玉大人,你說(shuō)我怎么就攤上這事⊙撸” “怎么了友瘤?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)檐束。 經(jīng)常有香客問我辫秧,道長(zhǎng),這世上最難降的妖魔是什么被丧? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任盟戏,我火速辦了婚禮,結(jié)果婚禮上甥桂,老公的妹妹穿的比我還像新娘抓半。我一直安慰自己,他們只是感情好格嘁,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著廊移,像睡著了一般糕簿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上狡孔,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天懂诗,我揣著相機(jī)與錄音,去河邊找鬼苗膝。 笑死殃恒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辱揭。 我是一名探鬼主播离唐,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼问窃!你這毒婦竟也來(lái)了亥鬓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤域庇,失蹤者是張志新(化名)和其女友劉穎嵌戈,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體听皿,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡熟呛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了尉姨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庵朝。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出偿短,到底是詐尸還是另有隱情欣孤,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布昔逗,位于F島的核電站降传,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏勾怒。R本人自食惡果不足惜婆排,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望笔链。 院中可真熱鬧段只,春花似錦、人聲如沸鉴扫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)坪创。三九已至炕婶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間莱预,已是汗流浹背柠掂。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留依沮,地道東北人涯贞。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像危喉,于是被迫代替她去往敵國(guó)和親宋渔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

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

  • 1姥饰、簡(jiǎn)介對(duì)稱加密算法又稱傳統(tǒng)加密算法傻谁。加密和解密使用同一個(gè) 密鑰。 1.1對(duì)稱加密算法示例密鑰:X加密算法:每個(gè)字...
    6ffd6634d577閱讀 2,999評(píng)論 0 2
  • 1.數(shù)據(jù)安全 01數(shù)據(jù)安全的原則1)在網(wǎng)絡(luò)上"不允許"傳輸用戶隱私數(shù)據(jù)的"明文"2.)在本地"不允許"保存用戶隱私...
    小楓123閱讀 452評(píng)論 0 1
  • 重新回到不喜不悲列粪、不驕不躁审磁、不瘋不鬧的狀態(tài),一直以為自己能夠好好的控制情緒岂座,只是發(fā)生一些事以后才知道情緒真的讓人“...
    一生跟隨閱讀 346評(píng)論 0 0
  • 虛度時(shí)光_d4fd閱讀 397評(píng)論 0 0