對稱算法
采用單鑰密碼的加密方法矩屁,同一個密鑰可以同時用來加密和解密冲甘,這種加密方法稱為對稱加密捷雕,也稱為單密鑰加密
常用的對稱加密算法:
DES:數(shù)據(jù)加密標(biāo)準(zhǔn)湾蔓,速度較快瘫析,適用于加密大量數(shù)據(jù)的場合(用得少,因為強(qiáng)度不夠)
3DES:是基于DES卵蛉,對一塊數(shù)據(jù)用3個不同的密鑰進(jìn)行3次加密颁股,強(qiáng)度更高
AES:高級加密標(biāo)準(zhǔn),是下一代的加密算法標(biāo)準(zhǔn)傻丝,速度快甘有,安全級別高,支持128葡缰、192亏掀、256忱反、512位密鑰的加密
算法特征:
加密方和解密方使用同一個密鑰
加密解密的速度比較快,適合數(shù)據(jù)比較長時的使用
密鑰傳輸?shù)倪^程不安全滤愕,且容易被破解温算,密鑰管理也比較麻煩
應(yīng)用模式
ECB(Electronic Code Book)
電子密碼本模式。每一塊數(shù)據(jù)间影,獨(dú)立加密注竿。最基本的加密模式,也就是通常理解的加密魂贬,相同的明文將永遠(yuǎn)加密成相同的密文巩割,無初始向量,容易受到密碼本重放攻擊付燥,一般情況下很少用宣谈。
CBC(Cipher Block Chaining)
密碼分組鏈接模式。使用一個密鑰和一個初始化向量iv對數(shù)據(jù)執(zhí)行加密明文被加密前要與前面的密文進(jìn)行異或運(yùn)算后再加密键科,因此只要選擇不同的初始向量闻丑,相同的密文加密后會形成不同的密文,這是目前應(yīng)用最廣泛的模式勋颖。CBC加密后的密文是上下文相關(guān)的嗦嗡,但明文的錯誤不會傳遞到后續(xù)分組,但如果一個分組丟失牙言,后面的分組將全部作廢(同步錯誤)CBC可以有效的保證密文的完整性酸钦,如果一個數(shù)據(jù)塊在傳遞是丟失或改變,后面的數(shù)據(jù)將無法正常解密咱枉。
向量iv的作用:
很多加密算法都和幾何圖形有關(guān)卑硫,幾何圖形的變量算法同樣具有規(guī)律性,但算法的規(guī)律結(jié)果變幻莫測蚕断。
例如:一個圓上有無數(shù)個點(diǎn)欢伏,如果把某一個點(diǎn)視為向量iv,加密結(jié)果則會有無數(shù)種亿乳,所以將幾何算法添加到加密算法中硝拧,它的破解難度系數(shù)變得更大。
用OC實現(xiàn)AES加解密
1葛假、導(dǎo)入頭文件 (Ps:Ivv是CBC模式的偏移向量障陶,ECB模式不需要)
#import <CommonCrypto/CommonCryptor.h>
#define Ivv @"0000000000000000" //偏移量,可自行修改
2、主要實現(xiàn)代碼:
加密部分:
#pragma mark - encrypt
+ (NSString *)encrypt:(NSString *)message password:(NSString *)password {
//將hexstring轉(zhuǎn)化為nsdata
NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding];
//使用密碼對nsdata進(jìn)行加密
NSData *encryptedData = [self AES128EncryptWithKey:password gIv:Ivv messageData:data];
//返回進(jìn)行16進(jìn)制轉(zhuǎn)碼的加密字符串
return [self hexStringFromData:encryptedData];
}
+ (NSData *)AES128EncryptWithKey:(NSString *)key gIv:(NSString *)Iv messageData:(NSData *)data{//加密
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCKeySizeAES128+1];
memset(ivPtr, 0, sizeof(ivPtr));
[Iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr,
kCCBlockSizeAES128,
ivPtr,
[data bytes],
dataLength,
buffer,
bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
//data數(shù)據(jù)轉(zhuǎn)hex string
+ (NSString *) hexStringFromData:(NSData*) data
{
NSUInteger i, len;
unsigned char *buf, *bytes;
len = data.length;
bytes = (unsigned char*)data.bytes;
//buf = malloc(len*2);
buf = (unsigned char *)malloc(len*2);
for (i=0; i<len; i++) {
buf[i*2] = itoh((bytes[i] >> 4) & 0xF);
buf[i*2+1] = itoh(bytes[i] & 0xF);
}
return [[NSString alloc] initWithBytesNoCopy:buf
length:len*2
encoding:NSASCIIStringEncoding
freeWhenDone:YES];
}
解密部分:
#pragma mark - decrypt
+ (NSString *)decrypt:(NSString *)encodedString password:(NSString *)password {
//hexstring轉(zhuǎn)data
NSData *strata = [EAccountSDKCommonUtil dataFromHexString:encodedString];
//使用密碼對data進(jìn)行解密
NSData *decryData = [self AES128DecryptWithKey:password gIv:Ivv decrypData:strata];
//將解了密碼的nsdata轉(zhuǎn)化為nsstring
NSString *str = [[NSString alloc] initWithData:decryData encoding:NSUTF8StringEncoding];
return str;
}
+ (NSData *)AES128DecryptWithKey:(NSString *)key gIv:(NSString *)Iv decrypData:(NSData *)data{//解密
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCKeySizeAES128+1];
memset(ivPtr, 0, sizeof(ivPtr));
[Iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr,
kCCBlockSizeAES128,
ivPtr,
[data bytes],
dataLength,
buffer,
bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
加解密都是通過系統(tǒng)的CCCrypt實現(xiàn)聊训,其中涉及11個參數(shù)抱究,稍微做下說明(Ps:CCCrypt函數(shù)的使用,盡量不要直接傳遞原文和key带斑,建議對其進(jìn)行異或加密鼓寺,然后再調(diào)用CCCrypt函數(shù))
CCCryptorStatus CCCrypt(
CCOperation op, kCCEncrypt 加密 / kCCDeccrypt 解密
CCAlgorithm alg, 加密算法
CCOptions options, 加密選項 ECB / CBC
const void *key, KEY的地址
size_t keyLength, KEY的長度
const void *iv, iv初始化向量
const void *dataIn, 加密的數(shù)據(jù)
size_t dataInLength, 加密數(shù)據(jù)的長度
void *dataOut, 密文的內(nèi)存地址
size_t dataOutAvailable, 密文緩沖區(qū)的大小
size_t *dataOutMoved 數(shù)據(jù)的指針(加密結(jié)果大醒狻)
)
AES算法原理
具體的原理有興趣的參考這篇博客:https://blog.csdn.net/qq_28205153/article/details/55798628