在密碼學(xué)中幔摸,加密部分主要分為對(duì)稱(chēng)加密和非對(duì)稱(chēng)加密,非對(duì)稱(chēng)加密主要有RSA非對(duì)稱(chēng)加密(使用公鑰/私鑰來(lái)加密解密)颤练,對(duì)稱(chēng)加密主要有DES/3DES/AES對(duì)稱(chēng)加密算法,順帶提一下我們今天介紹的Hash算法既忆,Hash屬于一種消息摘要算法,不屬于加密算法昔案,但是由于其單向運(yùn)算尿贫,不可逆性,所以Hash是加密算法中的構(gòu)成部分踏揣,Hash算法主要有MD5/Sha1/Sha2庆亡,這幾個(gè)只是Hash算法加密精度有所不同。
那么緊接之前的非對(duì)稱(chēng)加密RSA捞稿,直接上這次的干貨部分
1又谋、Hash概述2拼缝、數(shù)字簽名3、對(duì)稱(chēng)加密算法簡(jiǎn)介4彰亥、對(duì)稱(chēng)加密算法終端命令? ? 5咧七、對(duì)稱(chēng)加密算法終端演練6、對(duì)稱(chēng)加密算法代碼演練7任斋、CCCrypt函數(shù)復(fù)制代碼
一继阻、Hash概述
1、Hash的概念
Hash, 一般翻譯為'散列', 也有直接音譯的'哈希'废酷,就是把任意長(zhǎng)度的輸入瘟檩,通過(guò)散列算法變換成固定長(zhǎng)度的輸出,該輸出就是散列值澈蟆。這種轉(zhuǎn)換是一種壓縮映射墨辛,也就是散列值的空間通常小于輸入的空間,不同的輸入可能會(huì)散列成相同的輸出趴俘,所以不可能從散列值來(lái)確定唯一的輸入值睹簇。簡(jiǎn)單說(shuō)就是一種將任意長(zhǎng)度的消息壓縮到某一固定長(zhǎng)度的消息摘要的函數(shù)。
2寥闪、Hash特點(diǎn)
1太惠、算法是公開(kāi)的2、對(duì)相同的數(shù)據(jù)運(yùn)算橙垢,得到的結(jié)果是一樣的3垛叨、對(duì)于不同的數(shù)據(jù)運(yùn)算伦糯,如MD5(Hash算法的一種)的到的結(jié)果默認(rèn)是128位的柜某,32個(gè)字符(16進(jìn)制標(biāo)識(shí))4、沒(méi)法逆運(yùn)算(因?yàn)楣V凳怯成潢P(guān)系敛纲,會(huì)存在散列碰撞【即:無(wú)限個(gè)數(shù)據(jù)加密得到有限個(gè)數(shù)據(jù)喂击,就存在一個(gè)或許多個(gè)數(shù)據(jù)存在同樣的哈希值】)5、信息摘要淤翔,信息’指紋‘翰绊,一般是用來(lái)做數(shù)據(jù)識(shí)別的(由于沒(méi)法做逆運(yùn)算,所以一般不會(huì)用來(lái)做加密數(shù)據(jù)旁壮,只是把數(shù)據(jù)的哈希值取到监嗜,然后用來(lái)對(duì)比,做數(shù)據(jù)識(shí)別的)復(fù)制代碼
3抡谐、Hash函數(shù)(單向散列函數(shù))
1裁奇、MD5(Message Digest Algorithm 5)2、SHA(Secure Hash Algorithm)? SHA又分為:? SHA-1? SHA-2系列(224,256,384,512,512/224,512/256統(tǒng)稱(chēng)為SHA-2系列)3麦撵、MAC(Message Authentication Code)4刽肠、CRC(Cyclic Redundancy Check)5溃肪、SM3(國(guó)產(chǎn)哈希算法)復(fù)制代碼
4、Hash用途
1音五、用戶(hù)密碼的加密2惫撰、搜索引擎3、版權(quán)4躺涝、數(shù)字簽名(應(yīng)用簽名)復(fù)制代碼
5厨钻、HMAC
什么是HMAC?HMAC(Hash-based message authentication code)是一種使用Hash函數(shù)(單向散列函數(shù))來(lái)構(gòu)造消息認(rèn)證碼的方法坚嗜,利用哈希算法莉撇,以一個(gè)密鑰和一個(gè)消息為輸入,生成一個(gè)消息摘要作為輸出惶傻。主要是為了能讓人對(duì)對(duì)方身份正確性和消息有效性進(jìn)行驗(yàn)證棍郎,與消息摘要的最大不同,就是有簽名密鑰银室!
HMAC通過(guò)兩次hash兩個(gè)不同的key來(lái)生成涂佃。 目前還沒(méi)有發(fā)現(xiàn)有任何的方法來(lái)產(chǎn)生碰撞。
HMAC中所使用的單向散列函數(shù)并不僅限于一種蜈敢,任何高強(qiáng)度的Hash函數(shù)(單向散列函數(shù))都可以被用于HMAC辜荠。
比如使用SHA-1、SHA-224抓狭、SHA-256伯病、SHA-384、SHA-512所構(gòu)造的HMAC否过,分別稱(chēng)為HMAC-SHA1午笛、HMAC-SHA-224、HMAC-SHA-384苗桂、HMAC-SHA-512药磺。
二、數(shù)字簽名
1煤伟、什么是數(shù)字簽名
數(shù)字簽名就是用于鑒別數(shù)字信息的方法癌佩;
2、數(shù)字簽名
下面我們以電商支付金額這個(gè)場(chǎng)景來(lái)描述數(shù)字簽名的具體意義:
圖示中便锨,經(jīng)過(guò)RSA加密的原商品信息Hash值這個(gè)整體就叫做數(shù)字簽名围辙。
三、對(duì)稱(chēng)加密概述
1放案、對(duì)稱(chēng)加密算法定義:
對(duì)稱(chēng)加密方式:就是明文通過(guò)密鑰加密得到密文姚建。密文通過(guò)密鑰解密得到明文。
2卿叽、對(duì)稱(chēng)加密常見(jiàn)算法
1桥胞、DES(Data Encryption Standard):數(shù)據(jù)加密標(biāo)準(zhǔn)恳守,速度較快,適用于加密大量數(shù)據(jù)的場(chǎng)合贩虾;(題外話(huà):實(shí)際上用的不多催烘,因?yàn)榧用軓?qiáng)度不夠)2、3DES(Triple DES):是基于DES的對(duì)稱(chēng)算法缎罢,對(duì)相同的數(shù)據(jù)用3個(gè)不同的密鑰執(zhí)行3次加密伊群,強(qiáng)度更高;(題外話(huà):不過(guò)因?yàn)?個(gè)密鑰管理起來(lái)麻煩,所以一般不是很常用~一出生就掛掉了策精,很慘舰始。。咽袜。)3丸卷、RC2和RC4:用變長(zhǎng)密鑰對(duì)大量數(shù)據(jù)進(jìn)行加密,比DES快哦~4询刹、AES(Advanced Encryption Standard):高級(jí)加密標(biāo)準(zhǔn)谜嫉,是下一代的加密算法標(biāo)準(zhǔn),速度快凹联,安全級(jí)別高沐兰,在21世紀(jì)AES標(biāo)準(zhǔn)的一個(gè)實(shí)現(xiàn)是Rijndael算法;(題外話(huà):很安全蔽挠,蘋(píng)果的鑰匙串訪(fǎng)問(wèn)就是用的AES住闯,美國(guó)國(guó)家安全局也是用的AES,想要暴力破解基本不可能)復(fù)制代碼
3澳淑、對(duì)稱(chēng)加密應(yīng)用模式對(duì)稱(chēng)加密主要有兩種應(yīng)用模式比原,下面來(lái)詳細(xì)介紹一下
ECB(Electronic Code Book):電子密碼本模式。每一塊數(shù)據(jù)偶惠, 獨(dú)立加密春寿。
ECB是最基本的加密方式朗涩,也就是通常理解的加密忽孽,相同的明文將永遠(yuǎn)加密成相同的密文,無(wú)初始向量谢床,容易受到密碼本重放攻擊兄一,一般情況下很少用。
CBC(Cipher Block Chaining):密碼分組鏈接模式识腿。使用一個(gè)密鑰和一個(gè)初始化向量(IV)對(duì)數(shù)據(jù)進(jìn)行加密出革。
CBC加密方式,明文被加密前要與前面的密文進(jìn)行異或運(yùn)算后再加密渡讼,因此只要選擇不同的初始向量途凫,相同的密文加密后會(huì)形成不同的密文其做,這是目前應(yīng)用最廣泛的模式治筒。CBC加密后的密文是上下文相關(guān)的,但明文的錯(cuò)誤不會(huì)傳遞到后續(xù)分組旨枯,但如果一個(gè)分組丟失,后面的分組將全部作廢(同步錯(cuò)誤).
CBC可以有效的保證密文的完整性混驰,如果一個(gè)數(shù)據(jù)塊在傳遞時(shí)丟失或者改變攀隔,后面的數(shù)據(jù)無(wú)法進(jìn)行正常的解密。
四栖榨、對(duì)稱(chēng)加密算法終端命令
AES對(duì)稱(chēng)加密算法兩種應(yīng)用模式下的終端命令分別如下:1昆汹、AES(ECB)的加密與解密
AES(ECB)加密'battleMage'字符串
$echo-n battleMage | openssl enc -aes-128-ecb -K 616263 -nosalt | base64復(fù)制代碼
AES(ECB)解密'battleMage'字符串
$echo-n kXcE5nnetsinAMBEcK6D5g== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt-d復(fù)制代碼
2、AES(CBC)的加密與解密
AES(CBC)加密'battleMage'字符串
$echo-n battleMage | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64復(fù)制代碼
AES(CBC)解密'battleMage'字符串
$echo-n H3tn3dXCEtKNvijJYLsStw== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt-d復(fù)制代碼
五婴栽、對(duì)稱(chēng)加密算法終端演練對(duì)比
1满粗、新建一個(gè)message.txt文本文件
$ vi message.txt復(fù)制代碼
回車(chē)進(jìn)入編輯界面,點(diǎn)擊'i',進(jìn)入編輯界面愚争,輸入5排'1234567890'败潦,點(diǎn)擊'esc',再點(diǎn)擊'shift+:',輸入'wq'回車(chē)保存。
2准脂、對(duì)該'message.txt'文件直接使用AES(ECB)進(jìn)行加密劫扒,然后輸出一個(gè)'meg1.bin'文件
$ openssl enc -des-ecb -K 616263 -nosalt -in message.txt -out meg1.bin復(fù)制代碼
直接敲回車(chē),得到一個(gè) meg1.bin 的文件
然后直接修改message.txt文件狸膏,把最后一排的第一個(gè)1改成2沟饥,
再次使用上述命令進(jìn)行加密,然后輸出一個(gè)'meg2.bin'文件
$ openssl enc -des-ecb -K 616263 -nosalt -in message.txt -out meg2.bin復(fù)制代碼
直接敲回車(chē)湾戳,得到一個(gè) meg2.bin 的文件
接下來(lái)使用xxd命令查看meg1.bin 和 meg2.bin文件
同樣通過(guò)AES(CBC)加密'message.txt'并輸出一個(gè)‘meg3.bin’文件
$ openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -in message.txt -out meg3.bin復(fù)制代碼
再次手動(dòng)編輯message.txt文件贤旷,把message.txt還原,然后通過(guò)AES(CBC)加密并輸出一個(gè)‘meg4.bin’文件
$ openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -in message.txt -out meg4.bin復(fù)制代碼
對(duì)比如下圖砾脑,
六幼驶、對(duì)稱(chēng)加密算法代碼演練
接下來(lái)開(kāi)始代碼演練部分,需要導(dǎo)入一個(gè)工具類(lèi)韧衣,工具類(lèi)代碼并不多盅藻,這里直接貼工具類(lèi)的內(nèi)容吧,工具類(lèi)頭文件AES,DES各種終端命令也都包含在內(nèi)了:
.h文件
#import <Foundation/Foundation.h>#import <CommonCrypto/CommonCrypto.h>/** *? 終端測(cè)試指令 * *? 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> 加密過(guò)程是先加密畅铭,再base64編碼 *? ? ? 2> 解密過(guò)程是先base64解碼氏淑,再解密 */@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復(fù)制代碼
.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;? ? });returninstance;}? ? - (void)setAlgorithm:(uint32_t)algorithm {? ? _algorithm = algorithm;? ? switch (algorithm) {casekCCAlgorithmAES:? ? ? ? self.keySize = kCCKeySizeAES128;? ? ? ? self.blockSize = kCCBlockSizeAES128;break;casekCCAlgorithmDES:? ? ? ? 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);? ? ? ? // 開(kāi)始加密? ? size_t encryptedSize = 0;? ? //加密解密都是它 -- CCCrypt? ? 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);? ? ? ? // 開(kāi)始解密? ? 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復(fù)制代碼
接下來(lái)新建工程硕噩,把工具類(lèi).h,.m拖入工程假残,在ViewController.m實(shí)現(xiàn)touchBegin方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {? ? NSString * key = @"abc";? ? uint8_t iv[8] = {1,2,3,4,5,6,7,8};? ? ? ? //備注:選擇的是AES(ECB), 初始向量iv直接傳nil,如果選擇 AES(CBC)炉擅,初始向量iv需要傳值辉懒,具體可見(jiàn)工具類(lèi).m文件中實(shí)現(xiàn)阳惹,是判斷iv是否為nil來(lái)選取加密方式的? ? //1、選擇AES(ECB)? ? NSString * encStr =? [[EncryptionTools sharedEncryptionTools]encryptString:@"hello"keyString:key iv:nil];? ? ? ? NSLog(@"AES(ECB)加密的結(jié)果是:%@", encStr);? ? NSLog(@"AES(ECB)解密的結(jié)果是:%@", [[EncryptionTools sharedEncryptionTools]decryptString:encStr keyString:key iv:nil]);? ? ? ? //2眶俩、選擇AES(CBC)? ? NSData * ivData = [NSData dataWithBytes:iv length:sizeof(iv)];? ? NSString * encStr1 =? [[EncryptionTools sharedEncryptionTools]encryptString:@"hello"keyString:key iv:ivData];? ? ? ? NSLog(@"AES(CBC)加密的結(jié)果是:%@", encStr1);? ? NSLog(@"AES(CBC)解密的結(jié)果是:%@", [[EncryptionTools sharedEncryptionTools]decryptString:encStr1 keyString:key iv:ivData]);? ? }@end復(fù)制代碼
點(diǎn)擊運(yùn)行穆端,運(yùn)行結(jié)果OK
2019-10-12 21:57:26.858675+0800 CryptDemo[1790:115503] AES(ECB)加密的結(jié)果是:d1QG4T2tivoi0Kiu3NEmZQ==2019-10-12 21:57:26.858896+0800 CryptDemo[1790:115503] AES(ECB)解密的結(jié)果是:hello2019-10-12 21:57:26.859040+0800 CryptDemo[1790:115503] AES(CBC)加密的結(jié)果是:u3W/N816uzFpcg6pZ+kbdg==2019-10-12 21:57:26.859194+0800 CryptDemo[1790:115503] AES(CBC)解密的結(jié)果是:hello復(fù)制代碼
七、CCCrypt函數(shù)
第六步已經(jīng)使用過(guò)封裝好的加密工具類(lèi)EncryptionTools.h仿便,這個(gè)工具類(lèi)只是封裝了CCCrypt函數(shù)体啰,下面我們來(lái)研究一下加密工具的核心函數(shù)CCCrypt函數(shù):
使用CCCrypt函數(shù),需要引入系統(tǒng)庫(kù)
#import <CommonCrypto/CommonCrypto.h>復(fù)制代碼
不管是加密還是解密都是使用這個(gè)函數(shù)嗽仪,下面我們來(lái)介紹一下這個(gè)函數(shù)中的參數(shù)荒勇,參數(shù)解釋我直接備注在A(yíng)PI的后面,注意里面有坑N偶帷9料琛!
CCCrypt函數(shù)參數(shù)介紹1窿凤、 CCOperation op :操作類(lèi)型:加密or解密仅偎,枚舉值;? ? kCCEncrypt 代表加密? ? kCCDecrypt 代表解密2雳殊、 CCAlgorithm alg:加密算法橘沥,枚舉值;? ? kCCAlgorithmAES? ? 高級(jí)加密標(biāo)準(zhǔn)夯秃,128位(默認(rèn))? ? kCCAlgorithmDES? ? 數(shù)據(jù)加密標(biāo)準(zhǔn)? ? 3座咆、 CCOptions options:加密應(yīng)用模式,枚舉值仓洼;注意注意=樘铡!Iā2肝亍!;痢D巢小!F颉驾锰!這里有個(gè)坑;kCCOptionPKCS7Padding代表填充模式走越,這個(gè)options必須加上填充模式;? ? CCCrypt的option默認(rèn)是CBC,所以只需要補(bǔ)充一個(gè)填充模式就能代表CBC; 但是ECB就需要額外再加上一個(gè)kCCOptionECBMode耻瑟,所以選擇ECB就需要kCCOptionPKCS7Padding | kCCOptionECBMode;? ? ? ? 所以想要選擇CBC和ECB旨指,需要按下面進(jìn)行填寫(xiě)赏酥!kCCOptionPKCS7Padding;? 代表CBCkCCOptionPKCS7Padding | kCCOptionECBMode; 代表ECB4、 const void *key :加密的密鑰的指針5谆构、 size_t keyLength:密鑰的長(zhǎng)度6裸扶、 const void *iv: 初始化向量7、 const void *dataIn:加密的原始數(shù)據(jù)8搬素、 size_t dataInLength:加密的原始數(shù)據(jù)的長(zhǎng)度9呵晨、 void *dataOut:加密后密文的內(nèi)存地址10、size_t dataOutAvailable:加密后密文的緩沖區(qū)大小11熬尺、size_t *dataOutMoved :加密結(jié)果的大小CCCryptorStatus CCCrypt(? ? CCOperation op,? ? ? ? /* kCCEncrypt, etc. */? ? CCAlgorithm alg,? ? ? ? /* kCCAlgorithmAES128, etc. */? ? CCOptions options,? ? ? /* kCCOptionPKCS7Padding, etc. */? ? const void *key,? ? size_t keyLength,? ? const void *iv,? ? ? ? /* optional initialization vector */? ? const void *dataIn,? ? /* optional per op and alg */? ? size_t dataInLength,? ? void *dataOut,? ? ? ? ? /* data RETURNED here */? ? size_t dataOutAvailable,? ? size_t *dataOutMoved)復(fù)制代碼
需要注意的是摸屠,直接使用這個(gè)函數(shù)安全隱患非常的大!因?yàn)檫@個(gè)函數(shù)是系統(tǒng)提供的粱哼,不管你是加密還是解密季二,都是調(diào)用了CCCrypt函數(shù),而黑客可以通過(guò)越獄手機(jī)附加調(diào)試或者是非越獄手機(jī)重簽調(diào)試揭措,能夠用函數(shù)斷點(diǎn)斷到你的CCCrypt函數(shù)胯舷,然后通過(guò)寄存器直接獲取函數(shù)的對(duì)應(yīng)參數(shù),根據(jù)上面函數(shù)的介紹绊含,我們的數(shù)據(jù)其實(shí)是其中的第七個(gè)參數(shù)'const void *dataIn', 第七個(gè)參數(shù)的下標(biāo)為6, 然后調(diào)用匯編指令'x6',就可以拿到你的數(shù)據(jù)的地址桑嘶,然后轉(zhuǎn)一下類(lèi)型,就能直接打印出你的加密數(shù)據(jù)躬充!具體操作如下:
1不翩、還是打開(kāi)之前的工程,設(shè)置函數(shù)斷點(diǎn)CCCrypt麻裳,然后使用真機(jī)運(yùn)行?隍稹!津坑!必須用真機(jī)妙蔗,因?yàn)檎鏅C(jī)和模擬器的CPU不一樣
2、運(yùn)行工程疆瑰,模擬黑客調(diào)試眉反,然后點(diǎn)擊屏幕出發(fā)touchBegin方法,然后斷點(diǎn)停在了CCCrypt函數(shù)的地方
3穆役、因?yàn)楹瘮?shù)在調(diào)用的時(shí)候寸五,都是存在CPU的寄存器上,輸入寄存器查看指令
registerreadx6復(fù)制代碼
read x6是讀取該函數(shù)對(duì)應(yīng)的第7個(gè)參數(shù)耿币,第一個(gè)參數(shù)是x0
4梳杏、拿到地址,然后強(qiáng)轉(zhuǎn)類(lèi)型,蒙圈了吧十性,你的數(shù)據(jù)就泄漏了
所以這個(gè)函數(shù)不能直接使用叛溢,現(xiàn)在只說(shuō)基礎(chǔ),后面會(huì)詳細(xì)說(shuō)安全防護(hù)~今天就說(shuō)到這里了~
最后想要下面的資料可以加小編微信 獲取資料
其實(shí)劲适,看萬(wàn)卷書(shū)不如行萬(wàn)里路楷掉,平時(shí)直接上手做幾個(gè)簡(jiǎn)單的項(xiàng)目,然后在項(xiàng)目中學(xué)語(yǔ)法霞势,幾者相結(jié)合烹植,或許就離大神不遠(yuǎn)了
作者: BattleMage