一、base64
注意:準確來說一種編碼方式,編碼算法完全公開,可以逆向解碼。
1、簡介:
Base64編碼的思想是是采用64個基本的ASCII碼字符對數據進行重新編碼。它將需要編碼的數據拆分成字節數組。以3個字節為一組。按順序排列24位數據,再把這24位數據分成4組,即每組6位。再在每組的的最高位前補兩個0湊足一個字節。這樣就把一個3字節為一組的數據重新編碼成了4個字節。當所要編碼的數據的字節數不是3的整倍數,也就是說在分組時最后一組不夠3個字節。這時在最后一組填充1到2個0字節。并在最后編碼完成后在結尾添加1到2個“=”。例:將對ABC進行BASE64編碼首先取ABC對應的ASCII碼值。A(65)B(66)C(67)。再取二進制值A(01000001)B(01000010)C(01000011),然后把這三個字節的二進制碼接起來(010000010100001001000011),再以6位為單位分成4個數據塊并在最高位填充兩個0后形成4個字節的編碼后的值(00010000)(00010100)(00001001)(00000011)。藍色部分為真實數據。再把這四個字節數據轉化成10進制數得(16)(20)(19)(3)。最后根據BASE64給出的64個基本字符表,查出對應的ASCII碼字符(Q)(U)(J)(D)。這里的值實際就是數據在字符表中的索引。
注:BASE64字符表:包括大寫 A-Z 小寫 a-z 數字 0-9 和+ /
解碼過程就是把4個字節再還原成3個字節再根據不同的數據形式把字節數組重新整理成數據.
2、加密原則:
6 bit(原8bit) 一個字節. 不足的位數 用0 補齊.兩個0 用一個 = 表示.
3、加密特點
數據加密之后,數據量會變大,變大 1/3 左右.
4、示例代碼:
UIImage *image = [UIImage imageNamed:@"0.jpeg"];
NSData *data = UIImageJPEGRepresentation(image, 1.0);
NSData *base64Data = [data base64EncodedDataWithOptions:NSDataBase64Encoding64CharacterLineLength];
[base64Data writeToFile:@"/Users/chh/Desktop/123" atomically:YES];
// ???NSString *encodeStr = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSData *base64Data2 = [NSData dataWithContentsOfFile:@"/Users/chh/Desktop/123"];
NSData *baseData2 = [[NSData alloc] initWithBase64EncodedData:base64Data2 options:NSDataBase64DecodingIgnoreUnknownCharacters];
[baseData2 writeToFile:@"/Users/chh/Desktop/IMG_5551.jpeg" atomically:YES];
5、三方框架
GTMBase64:pod 'GTMBase64', '~> 1.0.0'(和系統的base64有區別)
二、MD5
1、簡介
MD5的全稱是Message-DigestAlgorithm 5,Message-Digest泛指字節串(Message)的Hash變換,就是把一個任意長度的字節串變換成一定長的大整數。請注意我使用了"字節串"而不是"字符串"這個詞,是因為這種變換只與字節的值有關,與字符集或編碼方式無關。 MD5將任意長度的"字節串"變換成一個128bit的大整數,并且它是一個不可逆的字符串變換算法,換句話說就是,即使你看到源程序和算法描述,也無法將一個MD5的值變換回原始的字符串,從數學原理上說,是因為原始的字符串有無窮多個,這有點象不存在反函數的數學函數。
MD5的典型應用是對一段Message(字節串)產生fingerprint(指紋),以防止被"篡改"。舉個例子,你將一段話寫在一個叫readme.txt文件中,并對這個readme.txt產生一個MD5的值并記錄在案,然后你可以傳播這個文件給別人,別人如果修改了文件中的任何內容,你對這個文件重新計算MD5時就會發現。如果再有一個第三方的認證機構,用MD5還可以防止文件作者的"抵賴",這就是所謂的數字簽名應用。
MD5還廣泛用于加密和解密技術上,在很多操作系統中,用戶的密碼是以MD5值(或類似的其它算法)的方式保存的,用戶Login的時候,系統是把用戶輸入的密碼計算成MD5值,然后再去和系統中保存的MD5值進行比較,而系統并不"知道"用戶的密碼是什么。
注: MD5加密是不可逆的,也就是說, MD5加密后是不能解密的,所謂的解密只是用大數據的”試用”,來測出結果的.
2、加密方式
NSString *password = @"zhang";
password = [password MD5];
備注:單純的 MD5加密是不安全的,因此要用到 MD5加鹽的方式
3、MD5加鹽
鹽值:MD5加鹽的值,加的鹽值越高越好.(鹽值可以隨意添加)
// 生成鹽值
NSString *salt = @"鹽值";
// 拼接鹽值
password = [password stringByAppendingString:salt];
// 加密
password = password.md5String;
4、第三方框架:
NSString+Hash
三、AES加密
AES加密解密需要專屬的key值,如下面的password,一般都是與Base64結合起來一起使用。
NSString *message = @"top secret message"; // message 為加密字符串 與密碼混合加密
NSString *password = @"p4ssw0rd"; // passwprd 為用戶輸入的密碼
NSString *encryptedData = [AESCrypt encrypt:message password:password]; //加密
NSString *message = [AESCrypt decrypt:encryptedData password:password]; //解密
第三方框架:
AESCrypt:pod 'AESCrypt', '~> 0.0.1'
四、DES
DES算法把64位的明文輸入塊變為64位的密文輸出塊,它所使用的密鑰也是64位(實際用到了56位,第8、16、24、32、40、48、56、64位是校驗位, 使得每個密鑰都有奇數個1),其算法主要分為兩步:
a、初始置換
其功能是把輸入的64位數據塊按位重新組合,并把輸出分為L0、R0兩部分,每部分各長32位,其置換規則為將輸入的第58位換到第一位,第50位換到第2位……依此類推,最后一位是原來的第7位。L0、R0則是換位輸出后的兩部分,L0是輸出的左32位,R0是右32位,例:設置換前的輸入值為D1D2D3……D64,則經過初始置換后的結果為:L0=D58D50……D8;R0=D57D49……D7。
其置換規則見下表:
58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7,
b、逆置換
經過16次迭代運算后,得到L16、R16,將此作為輸入,進行逆置換,逆置換正好是初始置換的逆運算,由此即得到密文輸出。
此算法是對稱加密算法體系中的代表,在計算機網絡系統中廣泛使用.
備注:數據加密標準,速度較快,適用于加密大量數據的場合。
詳情見#import "CommonFunc.h"
/******************************************************************************
函數名稱: + (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key
函數描述: 文本數據進行DES加密
輸入參數: (NSData *)data
(NSString *)key
輸出參數: N/A
返回參數: (NSData *)
備注信息: 此函數不可用于過長文本
******************************************************************************/
+ (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
/******************************************************************************
函數名稱: + (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key
函數描述: 文本數據進行DES解密
輸入參數: (NSData *)data
(NSString *)key
輸出參數: N/A
返回參數: (NSData *)
備注信息: 此函數不可用于過長文本
******************************************************************************/
+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
五、鑰匙串訪問
1、蘋果在iOS 7.0.3版本以后公布鑰匙串訪問的SDK.鑰匙串訪問接口是純C語言的.
2、鑰匙串使用AES 256加密算法,能夠保證用戶密碼的安全.
3、鑰匙串訪問的第三方框架SSKeychain,是對C語言框架的封裝.注意:不需要看源碼.
4、鑰匙串訪問的密碼保存在哪里?只有蘋果才知道.這樣進一步保障了用戶的密碼安全.
5、使用方法
Password :需要存儲的密碼信息.
Service :用來標識 app ,app的唯一標識符.
account :賬戶信息,當前密碼所對應的賬號.
a、利用鑰匙串進行加密
// 獲取應用程序唯一標識.
NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;
// 利用第三方框架,將用戶密碼保存在鑰匙串
[SSKeychain setPassword:self.pwdText.text forService:bundleId account:@"wpf"];
b、從鑰匙串加載密碼
self.pwdText.text = [SSKeychain passwordForService:bundleId account:@"wpf"];
6、第三方框架
SSKeychain:pod 'SSKeychain'
六、Token值
1、介紹
token 值: 登錄令牌.利用 token 值來判斷用戶的登錄狀態.類似于 MD5 加密之后的長字符串.
用戶登錄成功之后,在后端(服務器端)會根據用戶信息生成一個唯一的值.這個值就是 token 值.
2、基本使用
a、在服務器端(數據庫)會保存這個 token 值,以后利用這個 token 值來檢索對應的用戶信息,并且判斷用戶的登錄狀態.
b、用戶登錄成功之后,服務器會將生成的 token 值返回給 客戶端,在客戶端也會保存這個 token 值.(一般可以保存在 cookie 中,也可以自己手動確定保存位置(比如偏好設置.)).
c、以后客戶端在發送新的網絡請求的時候,會默認自動附帶這個 token 值(作為一個參數傳遞給服務器.).服務器拿到客戶端傳遞的 token 值跟保存在 數據庫中的 token 值做對比,以此來判斷用戶身份和登錄狀態.
3、判斷登錄狀態
如果客戶端沒有這個token 值,意味著沒有登錄成功過,提示用戶登錄.
如果客戶端有token 值,一般會認為登錄成功(需要驗證是否有效).不需要用戶再次登錄(輸入賬號和密碼信息).
4、拓展
有效期說明:
一般的app ,token值得失效時間都在 1 年以上.
特殊的app :銀行類 app /支付類 app :token值失效時間 15 分鐘左右.
一旦用戶信息改變(密碼改變),會在服務器生成新的 token 值,原來的 token值就會失效.需要再次輸入賬號和密碼,以得到生成的新的 token 值.
唯一性判斷: 每次登錄,都會生成一個新的token值.原來的 token 值就會失效.利用時間來判斷登錄的差異性。
發表評論 取消回復