版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.08.19 |
前言
在這個信息爆炸的年代蔫巩,特別是一些敏感的行業(yè)霹期,比如金融業(yè)和銀行卡相關(guān)等等叶组,這都對
app
的安全機(jī)制有更高的需求,很多大公司都有安全 部門历造,用于檢測自己產(chǎn)品的安全性甩十,但是及時是這樣,安全問題仍然被不斷曝出吭产,接下來幾篇我們主要說一下app
的安全機(jī)制侣监。感興趣的看我上面幾篇。
1. APP安全機(jī)制(一)—— 幾種和安全性有關(guān)的情況
2. APP安全機(jī)制(二)—— 使用Reveal查看任意APP的UI
3. APP安全機(jī)制(三)—— Base64加密
MD5基本了解
下面很大一部分內(nèi)容來自百度百科臣淤。
MD5
即Message - Digest Algorithm 5
(信息-摘要算法5)橄霉,用于確保信息傳輸完整一致。是計算機(jī)廣泛使用的雜湊算法之一(又譯摘要算法邑蒋、哈希算法)姓蜂,主流編程語言普遍已有MD5實現(xiàn)按厘。將數(shù)據(jù)(如漢字)運算為另一固定長度值,是雜湊算法的基礎(chǔ)原理覆糟,MD5的前身有MD2
刻剥、MD3
和MD4
。
MD5主要特征
MD5主要有一以下特征滩字。
- 壓縮性:任意長度的數(shù)據(jù)造虏,算出的MD5值長度都是固定的。
- 容易計算:從原數(shù)據(jù)計算出MD5值很容易麦箍。
- 抗修改性:對原數(shù)據(jù)進(jìn)行任何改動漓藕,哪怕只修改1個字節(jié),所得到的MD5值都有很大區(qū)別挟裂。
- 強抗碰撞:已知原數(shù)據(jù)和其MD5值享钞,想找到一個具有相同MD5值的數(shù)據(jù)(即偽造數(shù)據(jù))是非常困難的。
MD5的作用是讓大容量信息在用數(shù)字簽名軟件簽署私人密鑰前被"壓縮"成一種保密的格式(就是把一個任意長度的字節(jié)串變換成一定長的十六進(jìn)制數(shù)字串)诀蓉。除了MD5以外栗竖,其中比較有名的還有sha-1
、RIPEMD
以及Haval
等渠啤。
MD5應(yīng)用領(lǐng)域
下面看一下MD5主要應(yīng)用的方面狐肢。
一致性驗證
md5典型應(yīng)用是對一段信息(Message)
產(chǎn)生信息摘要(Message-Digest)
,以防止被篡改沥曹。我們常常在某些軟件下載站點的某軟件信息中看到其MD5值份名,它的作用就在于我們可以在下載該軟件后,對下載回來的文件用專門的軟件(如Windows MD5 Check等)做一次MD5校驗妓美,以確保我們獲得的文件與該站點提供的文件為同一文件僵腺。
具體來說文件的MD5值就像是這個文件的“數(shù)字指紋”。每個文件的MD5值是不同的壶栋,如果任何人對文件做了任何改動辰如,其MD5值也就是對應(yīng)的“數(shù)字指紋”就會發(fā)生變化。比如下載服務(wù)器針對一個文件預(yù)先提供一個MD5值贵试,用戶下載完該文件后琉兜,用我這個算法重新計算下載文件的MD5值,通過比較這兩個值是否相同锡移,就能判斷下載的文件是否出錯,或者說下載的文件是否被篡改了漆际。
利用MD5算法來進(jìn)行文件校驗的方案被大量應(yīng)用到軟件下載站淆珊、論壇數(shù)據(jù)庫、系統(tǒng)文件安全等方面奸汇。數(shù)字簽名
MD5的典型應(yīng)用是對一段Message
(字節(jié)串)產(chǎn)生fingerprint
(指紋)施符,以防止被“篡改”往声。舉個例子,你將一段話寫在一個叫 readme.txt文件中戳吝,并對這個readme.txt產(chǎn)生一個MD5的值并記錄在案浩销,然后你可以傳播這個文件給別人,別人如果修改了文件中的任何內(nèi)容听哭,你對這個文件重新計算MD5時就會發(fā)現(xiàn)(兩個MD5值不相同)慢洋。如果再有一個第三方的認(rèn)證機(jī)構(gòu),用MD5還可以防止文件作者的“抵賴”陆盘,這就是所謂的數(shù)字簽名應(yīng)用普筹。安全訪問認(rèn)證
MD5
還廣泛用于操作系統(tǒng)的登陸認(rèn)證上,如Unix
隘马、各類BSD
系統(tǒng)登錄密碼太防、數(shù)字簽名等諸多方面。
MD5算法原理
下面我們就看一下MD5
的算法原理酸员。
對MD5算法簡要的敘述可以為:MD5以512位分組來處理輸入的信息蜒车,且每一分組又被劃分為16個32位子分組,經(jīng)過了一系列的處理后幔嗦,算法的輸出由四個32位分組組成酿愧,將這四個32位分組級聯(lián)后將生成一個128位散列值。
總體的流程圖如下所示崭添,表示第i個分組寓娩,每次的運算都由前一輪的128位結(jié)果值和第i塊512bit值進(jìn)行運算。
1. 填充
在MD5算法中呼渣,首先需要對信息進(jìn)行填充棘伴,使其位長對512求余的結(jié)果等于448,并且填充必須進(jìn)行屁置,即使其位長對512求余的結(jié)果等于448焊夸。因此,信息的位長(Bits Length)將被擴(kuò)展至N*512+448蓝角,N為一個非負(fù)整數(shù)阱穗,N可以是零。
填充的方法如下:
- 在信息的后面填充一個1和無數(shù)個0使鹅,直到滿足上面的條件時才停止用0對信息的填充揪阶。
- 在這個結(jié)果后面附加一個以64位二進(jìn)制表示的填充前信息長度(單位為Bit),如果二進(jìn)制表示的填充前信息長度超過64位患朱,則取低64位鲁僚。
- 經(jīng)過這兩步的處理,信息的位長 = N512 + 448 + 64= (N+1)512,即長度恰好是512的整數(shù)倍冰沙。這樣做的原因是為滿足后面處理中對信息長度的要求侨艾。
2. 初始化變量
初始的128位值為初試鏈接變量,這些參數(shù)用于第一輪的運算拓挥,以大端字節(jié)序來表示唠梨,他們分別為:A = 0x01234567,B = 0x89ABCDEF侥啤,C = 0xFEDCBA98当叭,D = 0x76543210
。(每一個變量給出的數(shù)值是高字節(jié)存于內(nèi)存低地址愿棋,低字節(jié)存于內(nèi)存高地址科展,即大端字節(jié)序。在程序中變量A糠雨、B才睹、C、D的值分別為0x67452301甘邀,0xEFCDAB89琅攘,0x98BADCFE,0x10325476
)
3. 處理分組數(shù)據(jù)
每一分組的算法流程如下:
第一分組需要將上面四個鏈接變量復(fù)制到另外四個變量中:A到a松邪,B到b坞琴,C到c,D到d逗抑。從第二分組開始的變量為上一分組的運算結(jié)果剧辐,即A = a, B = b邮府, C = c荧关, D = d。主循環(huán)有四輪(MD4只有三輪)褂傀,每輪循環(huán)都很相似忍啤。第一輪進(jìn)行16次操作。每次操作對a仙辟、b同波、c和d中的其中三個作一次非線性函數(shù)運算,然后將所得結(jié)果加上第四個變量叠国,文本的一個子分組和一個常數(shù)未檩。再將所得結(jié)果向左環(huán)移一個不定的數(shù),并加上a粟焊、b冤狡、c或d中之一校赤。最后用該結(jié)果取代a、b筒溃、c或d中之一。
以下是每次操作中用到的四個非線性函數(shù)(每輪一個)沾乘。
F( X ,Y ,Z ) = ( X & Y ) | ( (~X) & Z )
G( X ,Y ,Z ) = ( X & Z ) | ( Y & (~Z) )
H( X ,Y ,Z ) =X ^ Y ^ Z
I( X ,Y ,Z ) =Y ^ ( X | (~Z) )
(&是與(And)怜奖,|是或(Or),~是非(Not)翅阵,^是異或(Xor))
這四個函數(shù)的說明:如果X歪玲、Y和Z的對應(yīng)位是獨立和均勻的,那么結(jié)果的每一位也應(yīng)是獨立和均勻的掷匠。
F是一個逐位運算的函數(shù)滥崩。即,如果X讹语,那么Y钙皮,否則Z。函數(shù)H是逐位奇偶操作符顽决。假設(shè)Mj表示消息的第j個子分組(從0到15)短条,常數(shù)ti是4294967296*abs( sin(i) )的整數(shù)部分,i 取值從1到64才菠,單位是弧度茸时。(4294967296=232)
現(xiàn)定義:
FF(a ,b ,c ,d ,Mj ,s ,ti )
操作為 a = b + ( (a + F(b,c,d) + Mj + ti) << s)
GG(a ,b ,c ,d ,Mj ,s ,ti )
操作為 a = b + ( (a + G(b,c,d) + Mj + ti) << s)
HH(a ,b ,c ,d ,Mj ,s ,ti)
操作為 a = b + ( (a + H(b,c,d) + Mj + ti) << s)
II(a ,b ,c ,d ,Mj ,s ,ti)
操作為 a = b + ( (a + I(b,c,d) + Mj + ti) << s)
注意:“<<”表示循環(huán)左移位,不是左移位赋访。
這四輪(共64步)是:
- 第一輪
FF(a ,b ,c ,d ,M0 ,7 ,0xd76aa478 )
FF(d ,a ,b ,c ,M1 ,12 ,0xe8c7b756 )
FF(c ,d ,a ,b ,M2 ,17 ,0x242070db )
FF(b ,c ,d ,a ,M3 ,22 ,0xc1bdceee )
FF(a ,b ,c ,d ,M4 ,7 ,0xf57c0faf )
FF(d ,a ,b ,c ,M5 ,12 ,0x4787c62a )
FF(c ,d ,a ,b ,M6 ,17 ,0xa8304613 )
FF(b ,c ,d ,a ,M7 ,22 ,0xfd469501)
FF(a ,b ,c ,d ,M8 ,7 ,0x698098d8 )
FF(d ,a ,b ,c ,M9 ,12 ,0x8b44f7af )
FF(c ,d ,a ,b ,M10 ,17 ,0xffff5bb1 )
FF(b ,c ,d ,a ,M11 ,22 ,0x895cd7be )
FF(a ,b ,c ,d ,M12 ,7 ,0x6b901122 )
FF(d ,a ,b ,c ,M13 ,12 ,0xfd987193 )
FF(c ,d ,a ,b ,M14 ,17 ,0xa679438e )
FF(b ,c ,d ,a ,M15 ,22 ,0x49b40821 )
- 第二輪
GG(a ,b ,c ,d ,M1 ,5 ,0xf61e2562 )
GG(d ,a ,b ,c ,M6 ,9 ,0xc040b340 )
GG(c ,d ,a ,b ,M11 ,14 ,0x265e5a51 )
GG(b ,c ,d ,a ,M0 ,20 ,0xe9b6c7aa )
GG(a ,b ,c ,d ,M5 ,5 ,0xd62f105d )
GG(d ,a ,b ,c ,M10 ,9 ,0x02441453 )
GG(c ,d ,a ,b ,M15 ,14 ,0xd8a1e681 )
GG(b ,c ,d ,a ,M4 ,20 ,0xe7d3fbc8 )
GG(a ,b ,c ,d ,M9 ,5 ,0x21e1cde6 )
GG(d ,a ,b ,c ,M14 ,9 ,0xc33707d6 )
GG(c ,d ,a ,b ,M3 ,14 ,0xf4d50d87 )
GG(b ,c ,d ,a ,M8 ,20 ,0x455a14ed )
GG(a ,b ,c ,d ,M13 ,5 ,0xa9e3e905 )
GG(d ,a ,b ,c ,M2 ,9 ,0xfcefa3f8 )
GG(c ,d ,a ,b ,M7 ,14 ,0x676f02d9 )
GG(b ,c ,d ,a ,M12 ,20 ,0x8d2a4c8a )
- 第三輪
HH(a ,b ,c ,d ,M5 ,4 ,0xfffa3942 )
HH(d ,a ,b ,c ,M8 ,11 ,0x8771f681 )
HH(c ,d ,a ,b ,M11 ,16 ,0x6d9d6122 )
HH(b ,c ,d ,a ,M14 ,23 ,0xfde5380c )
HH(a ,b ,c ,d ,M1 ,4 ,0xa4beea44 )
HH(d ,a ,b ,c ,M4 ,11 ,0x4bdecfa9 )
HH(c ,d ,a ,b ,M7 ,16 ,0xf6bb4b60 )
HH(b ,c ,d ,a ,M10 ,23 ,0xbebfbc70 )
HH(a ,b ,c ,d ,M13 ,4 ,0x289b7ec6 )
HH(d ,a ,b ,c ,M0 ,11 ,0xeaa127fa )
HH(c ,d ,a ,b ,M3 ,16 ,0xd4ef3085 )
HH(b ,c ,d ,a ,M6 ,23 ,0x04881d05 )
HH(a ,b ,c ,d ,M9 ,4 ,0xd9d4d039 )
HH(d ,a ,b ,c ,M12 ,11 ,0xe6db99e5 )
HH(c ,d ,a ,b ,M15 ,16 ,0x1fa27cf8 )
HH(b ,c ,d ,a ,M2 ,23 ,0xc4ac5665 )
- 第四輪
II(a ,b ,c ,d ,M0 ,6 ,0xf4292244 )
II(d ,a ,b ,c ,M7 ,10 ,0x432aff97 )
II(c ,d ,a ,b ,M14 ,15 ,0xab9423a7 )
II(b ,c ,d ,a ,M5 ,21 ,0xfc93a039 )
II(a ,b ,c ,d ,M12 ,6 ,0x655b59c3 )
II(d ,a ,b ,c ,M3 ,10 ,0x8f0ccc92 )
II(c ,d ,a ,b ,M10 ,15 ,0xffeff47d )
II(b ,c ,d ,a ,M1 ,21 ,0x85845dd1 )
II(a ,b ,c ,d ,M8 ,6 ,0x6fa87e4f )
II(d ,a ,b ,c ,M15 ,10 ,0xfe2ce6e0 )
II(c ,d ,a ,b ,M6 ,15 ,0xa3014314 )
II(b ,c ,d ,a ,M13 ,21 ,0x4e0811a1 )
II(a ,b ,c ,d ,M4 ,6 ,0xf7537e82 )
II(d ,a ,b ,c ,M11 ,10 ,0xbd3af235 )
II(c ,d ,a ,b ,M2 ,15 ,0x2ad7d2bb )
II(b ,c ,d ,a ,M9 ,21 ,0xeb86d391 )
所有這些完成之后可都,將a、b蚓耽、c渠牲、d分別在原來基礎(chǔ)上再加上A、B田晚、C嘱兼、D。即 a = a + A贤徒,b = b + B芹壕,c = c + C,d = d + D
接奈,然后用下一分組數(shù)據(jù)繼續(xù)運行以上算法踢涌。
4. 輸出
最后的輸出是a、b序宦、c和d的級聯(lián)睁壁。當(dāng)你按照我上面所說的方法實現(xiàn)MD5算法以后,你可以用以下幾個信息對你做出來的程序作一個簡單的測試,看看程序有沒有錯誤潘明。
MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") =
f29939a25efabaef3b87e2cbfe641315
MD5 ("8a683566bcc7801226b3d8b0cf35fd97") =cf2cb5c89c5e5eeebef4a76becddfcfd
MD5一個簡單實例
下面看一個MD5的實例行剂。
現(xiàn)以字符串“jklmn”
為例。
該字符串在內(nèi)存中表示為:6A 6B 6C 6D 6E
(從左到右為低地址到高地址钳降,后同)厚宰,信息長度為40 bits, 即0x28遂填。
對其填充铲觉,填充至448位,即56字節(jié)吓坚。結(jié)果為:
6A 6B 6C 6D 6E 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
剩下64位撵幽,即8字節(jié)填充填充前信息位長,按小端字節(jié)序填充剩下的8字節(jié)礁击,結(jié)果為:
6A 6B 6C 6D 6E 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 28 00 00 00 00 00 00 00
(64字節(jié)盐杂,512 bits)
初始化A扩借、B廊佩、C、D四個變量渊季。
將這64字節(jié)填充后數(shù)據(jù)分成16個小組(程序中對應(yīng)為16個數(shù)組)更耻,即:
M0:6A 6B 6C 6D (這是內(nèi)存中的順序测垛,按照小端字節(jié)序原則,對應(yīng)數(shù)組M(0)的值為0x6D6C6B6A秧均,下同)
M1:6E 80 00 00
M2:00 00 00 00
.....
M14:28 00 00 00
M15:00 00 00 00
經(jīng)過3. 分組數(shù)據(jù)處理
后食侮,a、b目胡、c锯七、d值分別為0xD8523F60、0x837E0144誉己、0x517726CA眉尸、0x1BB6E5FE
。
在內(nèi)存中為:
a:60 3F 52 D8
b:44 01 7E 83
c:CA 26 77 51
d:FE E5 B6 1B
a巨双、b噪猾、c、d按內(nèi)存順序輸出即為最終結(jié)果:603F52D844017E83CA267751FEE5B61B
筑累。這就是字符串“jklmn”的MD5值袱蜡。
MD5在ios系統(tǒng)中的應(yīng)用
下面我們就看一下ios中MD5是如何加密的,下面還是直接看代碼慢宗。
#import "JJMD5VC.h"
#import <CommonCrypto/CommonDigest.h>
@interface JJMD5VC ()
@end
@implementation JJMD5VC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor lightGrayColor];
[self beginMD5ProcessWithString:@"jklmn"];
}
#pragma mark - Object Private Function
- (void)beginMD5ProcessWithString:(NSString *)string
{
//傳入?yún)?shù),轉(zhuǎn)化成char
const char * str = [string UTF8String];
//開辟一個16字節(jié)(128位:md5加密出來就是128位/bit)的空間(一個字節(jié)=8字位=8個二進(jìn)制數(shù))
unsigned char md[CC_MD5_DIGEST_LENGTH];
/*
*extern unsigned char * CC_MD5(const void *data, CC_LONG len, unsigned char *md)官方封裝好的加密方法
* 把str字符串轉(zhuǎn)換成了32位的16進(jìn)制數(shù)列(這個過程不可逆轉(zhuǎn)) 存儲到了md這個空間中
*
*/
CC_MD5(str, (int)strlen(str), md);
//創(chuàng)建一個可變字符串收集結(jié)果
NSMutableString * ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH];
for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
/**
X 表示以十六進(jìn)制形式輸入/輸出
02 表示不足兩位坪蚁,前面補0輸出奔穿;出過兩位不影響
printf("%02X", 0x123); //打印出:123
printf("%02X", 0x1); //打印出:01
*/
[ret appendFormat:@"%02X",md[i]];
}
NSLog(@"%@",ret);
}
@end
注意要引入頭文件
#import <CommonCrypto/CommonDigest.h>
下面看輸出結(jié)果
2017-08-19 18:08:25.595 JJOC[9099:303472] 603F52D844017E83CA267751FEE5B61B
可見,實現(xiàn)了加密敏晤,輸出了加密結(jié)果贱田。
MD5是不可逆轉(zhuǎn)和破解的,但是嘴脾,網(wǎng)上還是有很多暴力破解工具湘换,舉一個例子,這里就有個網(wǎng)站统阿。
我們看一下破解結(jié)果
對比輸出結(jié)果,可見是正確的筹我,這里暴力破解并不是算法上的破解扶平,而是將很多組合的MD5存儲,到時候直接查詢和嘗試獲得的結(jié)果蔬蕊。
這里還要注意:
- 一定要和后臺開發(fā)人員約定好结澄,MD5加密的位數(shù)是16位還是32位(大多數(shù)都是32位的),16位的可以通過32位的轉(zhuǎn)換得到岸夯。
- MD5加密區(qū)分 大小寫麻献,使用時要和后臺約定好。
參考文章
1. iOS MD5加密
2. iOS開發(fā) 關(guān)于MD5加密的相關(guān)使用
后記
未完猜扮,待續(xù)~~~