完整文章列表:
iOS的簽名與證書機(jī)制(一):加密解密
iOS的簽名與證書機(jī)制(二):單向散列函數(shù)
iOS的簽名與證書機(jī)制(三):數(shù)字簽名與證書
iOS的簽名與證書機(jī)制(四):iOS的簽名
單向散列函數(shù)(One-way hash function),也稱之為消息摘要函數(shù)(Message Digest Function),哈希函數(shù),它可以根據(jù)消息的內(nèi)容計算出一個散列值,這個散列值,我們可以看做是這個消息的數(shù)字指紋,而且不管消息的內(nèi)容多少,小到幾個字節(jié),大到你珍藏多年的學(xué)習(xí)資料,都會被壓縮為一段固定長度的散列值,這是一個有損壓縮的過程.
之所以要學(xué)習(xí)單向散列函數(shù),是為了下一章的數(shù)字簽名打下基礎(chǔ);
翠花繼續(xù)上圖:
SHA1散列函數(shù).png
我們來看看單向散列函數(shù)的特點:
- 任意長度的信息,計算出固定的散列值;
- 單向性,即不可逆性,從散列值不能計算出原有的消息,不過對于MD5以及SHA-1算法,目前證明可以被破解,這里要介紹一下王小云教授,帶領(lǐng)中國團(tuán)隊破解了這兩種算法;
- 如果明文不一樣,那么散列后的結(jié)果一定不一樣;
- 如果明文一樣,散列后的結(jié)果一定一樣;
常見的單向散列函數(shù)有以下幾種:
- MD4,MD5:Message Digest 4(5),產(chǎn)生的是128bit的散列值,目前已經(jīng)不安全,可以被暴力破解;
在我們的Mac終端,可以直接使用md5命令;
在項目中我們經(jīng)常使用的是對用戶密碼等隱私信息進(jìn)行MD5加密,然后發(fā)送到服務(wù)器,下面就是我們常用的MD5加密代碼
#import <CommonCrypto/CommonCrypto.h>
@implementation NSString (MD5)
#pragma mark - 32位 小寫
- (NSString *)MD5ForLower32Bate{
//要進(jìn)行UTF8的轉(zhuǎn)碼
const char* input = [self UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(input, (CC_LONG)strlen(input), result);
NSMutableString *digest = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for (NSInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[digest appendFormat:@"%02x", result[i]];
} return digest; }
- SHA-1:Secure Hash Algorithm 1,安全散列算法1,產(chǎn)生160bit的散列值,目前已不安全,下面我也會附上iOS項目中使用該算法加密的代碼;
- SHA-2:包括了SHA-256,SHA-384,SHA-512,對應(yīng)的計算出的散列值長度為256bit,384bit,512bit;
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonHMAC.h>
@implementation NSString (Hash)
- (NSString *)sha1String
{
const char *string = self.UTF8String;
int length = (int)strlen(string);
unsigned char bytes[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(string, length, bytes);
return [self stringFromBytes:bytes length:CC_SHA1_DIGEST_LENGTH];
}
- (NSString *)sha256String
{
const char *string = self.UTF8String;
int length = (int)strlen(string);
unsigned char bytes[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(string, length, bytes);
return [self stringFromBytes:bytes length:CC_SHA256_DIGEST_LENGTH];
}
- (NSString *)sha512String
{
const char *string = self.UTF8String;
int length = (int)strlen(string);
unsigned char bytes[CC_SHA512_DIGEST_LENGTH];
CC_SHA512(string, length, bytes);
return [self stringFromBytes:bytes length:CC_SHA512_DIGEST_LENGTH];
}
- (NSString *)stringFromBytes:(unsigned char *)bytes length:(NSInteger)length
{
NSMutableString *mutableString = @"".mutableCopy;
for (NSInteger i = 0; i < length; i++)
[mutableString appendFormat:@"%02x", bytes[i]];
return [NSString stringWithString:mutableString];
}
- SHA-3:包括了SHA3-256,SHA3-384,SHA3-512,對應(yīng)的計算出的散列值長度為256bit,384bit,512bit,這也是現(xiàn)在全新的標(biāo)準(zhǔn);
那么單向散列函數(shù)可以應(yīng)用在哪些方面呢?
-
隱私信息加密傳輸;
當(dāng)用戶在客戶端填寫完賬號密碼向服務(wù)器驗證的時候,密碼絕對不能明文傳輸,或者說我們在服務(wù)器中保存的只是用戶密碼的哈希值,每次用兩個哈希值進(jìn)行比較;
口令加密.png - 文件識別,防止數(shù)據(jù)被篡改;
很多unix軟件下載的時候,在文件的下載地址下方會有一個散列值,同時還會提供一套計算文件散列值的小工具,當(dāng)你下載完畢的時候,計算出下載文件的散列值與官方的進(jìn)行對比,如果一致則說明軟件是安全的,沒有被篡改過;
比如這個軟件:https://www.realvnc.com/en/connect/download/vnc/;
這也正是下一章的數(shù)字簽名會用到的特性; - 保存文件與圖片的唯一性,防止重復(fù)下載;
很多App需要從服務(wù)器下載圖片或者文件,存儲在本地的時候,可以用下載地址的md5散列值來作為文件名.下載之前,可以通過下載地址的md5散列值來檢查本地是否已經(jīng)有了該文件,避免重復(fù)下載;
看到這里,需要小伙伴記住的是:消息摘要,作為信息的簽名和指紋,可以把大量信息壓縮為一個固定長度的散列值,可以驗證消息是否被篡改;
在下一章的數(shù)字簽名中,小伙伴就可以看到它的具體應(yīng)用;