iOS中的加密算法
對(duì)稱(chēng)加密算法AES算法
AES加密算法涉及4種操作:字節(jié)替代(SubBytes)倒槐、行移位(ShiftRows)姑蓝、列混淆(MixColumns)和輪密鑰加(AddRoundKey)廷粒。下圖給出了AES加解密的流程,從圖中可以看出:
1)解密算法的每一步分別對(duì)應(yīng)加密算法的逆操作
2)加解密所有操作的順序正好是相反的
正是由于這幾點(diǎn)(再加上加密算法與解密算法每步的操作互逆)保證了算法的正確性。加解密中每輪的密鑰分別由種子密鑰經(jīng)過(guò)密鑰擴(kuò)展算法得到宴霸。算法中16字節(jié)的明文姆坚、密文和輪子密鑰都以一個(gè)4x4的矩陣表示澳泵。
https://www.cnblogs.com/luop/p/4334160.html
RSA算法(非對(duì)稱(chēng)加密算法)
RSA密碼體制是一種公鑰密碼體制,公鑰公開(kāi)兼呵,私鑰保密兔辅,它的加密解密算法是公開(kāi)的。 由公鑰加密的內(nèi)容可以并且只能由私鑰進(jìn)行解密萍程,并且由私鑰加密的內(nèi)容可以并且只能由公鑰進(jìn)行解密幢妄。也就是說(shuō),RSA的這一對(duì)公鑰茫负、私鑰都可以用來(lái)加密和解密蕉鸳,并且一方加密的內(nèi)容可以由并且只能由對(duì)方進(jìn)行解密。
對(duì)稱(chēng)加密算法:
1)甲方選擇某一種加密規(guī)則,對(duì)信息進(jìn)行加密潮尝;
2)乙方使用同一種規(guī)則榕吼,對(duì)信息進(jìn)行解密。
問(wèn)題出現(xiàn)在哪勉失? 保存和傳遞密鑰羹蚣,就成了最頭疼的問(wèn)題。
非對(duì)稱(chēng)加密算法
1)乙方生成兩把密鑰(公鑰和私鑰)乱凿。公鑰是公開(kāi)的顽素,任何人都可以獲得,私鑰則是保密的徒蟆。
2)甲方獲取乙方的公鑰胁出,然后用它對(duì)信息加密。
3)乙方得到加密后的信息段审,用私鑰解密全蝶。
4)甲方同樣可以通過(guò)公鑰去解密私鑰加密過(guò)的數(shù)據(jù)。
RSA算法原理
簡(jiǎn)單說(shuō)一下常用的非對(duì)稱(chēng)加密算法 RSA 的數(shù)學(xué)原理寺枉,理解簡(jiǎn)單的數(shù)學(xué)原理抑淫,就可以理解非對(duì)稱(chēng)加密是怎么做到的,為什么會(huì)是安全的:
1. 選兩個(gè)質(zhì)數(shù) p 和 q姥闪,相乘得出一個(gè)大整數(shù)n始苇,例如 p = 61,q = 53甘畅,n = p*q = 3233
2. 選 1-n 間的隨便一個(gè)質(zhì)數(shù)e埂蕊,例如 e = 17
3. 經(jīng)過(guò)一系列數(shù)學(xué)公式,算出一個(gè)數(shù)字 d疏唾,滿(mǎn)足:
a.通過(guò) n 和 e 這兩個(gè)數(shù)據(jù)一組數(shù)據(jù)進(jìn)行數(shù)學(xué)運(yùn)算后蓄氧,可以通過(guò) n 和 d 去反解運(yùn)算,反過(guò)來(lái)也可以槐脏。
b.如果只知道 n 和 e喉童,要推導(dǎo)出 d,需要知道 p 和 q顿天,也就是要需要把 n 因數(shù)分解堂氯。
上述的 (n,e) 這兩個(gè)數(shù)據(jù)在一起就是公鑰,(n,d) 這兩個(gè)數(shù)據(jù)就是私鑰牌废,滿(mǎn)足用私鑰加密咽白,公鑰解密,或反過(guò)來(lái)公鑰加密鸟缕,私鑰解密晶框,也滿(mǎn)足在只暴露公鑰 (只知道 n 和 e)的情況下排抬,要推導(dǎo)出私鑰 (n,d),需要把大整數(shù) n 因數(shù)分解授段。目前因數(shù)分解只能靠暴力窮舉蹲蒲,而 n 數(shù)字越大,越難以用窮舉計(jì)算出因數(shù) p 和 q侵贵,也就越安全届搁,當(dāng) n 大到二進(jìn)制 1024 位或 2048 位時(shí),以目前技術(shù)要破解幾乎不可能窍育,所以非常安全卡睦。
具體計(jì)算可以詳讀這兩篇文章:RSA 算法原理 一、二
RSA算法的使用
簽名和加密
我們說(shuō)加密漱抓,是指對(duì)某個(gè)內(nèi)容加密么翰,加密后的內(nèi)容還可以通過(guò)解密進(jìn)行還原。 比如我們把一封郵件進(jìn)行加密辽旋,加密后的內(nèi)容在網(wǎng)絡(luò)上進(jìn)行傳輸,接收者在收到后檐迟,通過(guò)解密可以還原郵件的真實(shí)內(nèi)容补胚。
簽名就是在信息的后面再加上一段內(nèi)容,可以證明信息沒(méi)有被修改過(guò)追迟,怎么樣可以達(dá)到這個(gè)效果呢溶其?
一般是對(duì)信息做一個(gè)hash計(jì)算得到一個(gè)hash值,注意敦间,這個(gè)過(guò)程是不可逆的瓶逃,也就是說(shuō)無(wú)法通過(guò)hash值得出原來(lái)的信息內(nèi)容。在把信息發(fā)送出去時(shí)廓块,把這個(gè)hash值加密后做為一個(gè)簽名和信息一起發(fā)出去厢绝。 接收方在收到信息后,會(huì)重新計(jì)算信息的hash值带猴,并和信息所附帶的hash值(解密后)進(jìn)行對(duì)比昔汉,如果一致,就說(shuō)明信息的內(nèi)容沒(méi)有被修改過(guò)拴清,因?yàn)檫@里hash計(jì)算可以保證不同的內(nèi)容一定會(huì)得到不同的hash值靶病,所以只要內(nèi)容一被修改,根據(jù)信息內(nèi)容計(jì)算的hash值就會(huì)變化状飞。當(dāng)然的烁,不懷好意的人也可以修改信息內(nèi)容的同時(shí)也修改hash戳晌。
iOS中的使用
https最為直觀。 我們?cè)貯FNetworking中可以看到RSA的應(yīng)用
SecKeyEncrypt:使用公鑰對(duì)數(shù)據(jù)進(jìn)行加密
SecKeyDecrypt:使用私鑰對(duì)數(shù)據(jù)進(jìn)行解密
SecKeyRawVerify:使用公鑰對(duì)數(shù)字簽名和數(shù)據(jù)進(jìn)行驗(yàn)證煤辨,以確認(rèn)該數(shù)據(jù)的來(lái)源合法性。
SecKeyRawSign:使用私鑰對(duì)數(shù)據(jù)進(jìn)行摘要并生成數(shù)字簽名
MD5算法
MD5消息摘要算法,屬Hash算法一類(lèi)掷酗。MD5算法對(duì)輸入任意長(zhǎng)度的消息進(jìn)行運(yùn)行调违,產(chǎn)生一個(gè)128位的消息摘要。MD5已經(jīng)廣泛使用在為文件傳輸提供一定的可靠性方面泻轰。例如技肩,服務(wù)器預(yù)先提供一個(gè)MD5校驗(yàn)和,用戶(hù)下載完文件以后浮声,用MD5算法計(jì)算下載文件的MD5校驗(yàn)和虚婿,然后通過(guò)檢查這兩個(gè)校驗(yàn)和是否一致,就能判斷下載的文件是否出錯(cuò)泳挥。
算法原理
MD5以512位分組來(lái)處理輸入的信息然痊,且每一分組又被劃分為16個(gè)32位子分組,經(jīng)過(guò)了一系列的處理后屉符,算法的輸出由四個(gè)32位分組組成剧浸,將這四個(gè)32位分組級(jí)聯(lián)后將生成一個(gè)128位散列值
算法用途
1、防止被篡改
比如發(fā)送一個(gè)電子文檔矗钟,發(fā)送前唆香,我先得到MD5的輸出結(jié)果a。然后在對(duì)方收到電子文檔后吨艇,對(duì)方也得到一個(gè)MD5的輸出結(jié)果b躬它。如果a與b一樣就代表中途未被篡改。
比如我提供文件下載东涡,為了防止不法分子在安裝程序中添加木馬冯吓,我可以在網(wǎng)站上公布由安裝文件得到的MD5輸出結(jié)果。
SVN在檢測(cè)文件是否在CheckOut后被修改過(guò)疮跑,也是用到了MD5组贺。
2、防止直接看到明文
現(xiàn)在很多網(wǎng)站在數(shù)據(jù)庫(kù)存儲(chǔ)用戶(hù)的密碼的時(shí)候都是存儲(chǔ)用戶(hù)密碼的MD5值祸挪。這樣就算不法分子得到數(shù)據(jù)庫(kù)的用戶(hù)密碼的MD5值锣披,也無(wú)法知道用戶(hù)的密碼(其實(shí)這樣是不安全的,后面我會(huì)提到)贿条。
經(jīng)加密后存儲(chǔ)在文件系統(tǒng)中雹仿。當(dāng)用戶(hù)登錄的時(shí)候,系統(tǒng)把用戶(hù)輸入的密碼計(jì)算成MD5值整以,然后再去和保存在文件系統(tǒng)中的MD5值進(jìn)行比較胧辽,進(jìn)而確定輸入的密碼是否正確。通過(guò)這樣的步驟公黑,系統(tǒng)在并不知道用戶(hù)密碼的明碼的情況下就可以確定用戶(hù)登錄系統(tǒng)的合法性邑商。這不但可以避免用戶(hù)的密碼被具有系統(tǒng)管理員權(quán)限的用戶(hù)知道摄咆,而且還在一定程度上增加了密碼被破解的難度。)
3人断、數(shù)字簽名
這需要一個(gè)第三方認(rèn)證機(jī)構(gòu)吭从。例如A寫(xiě)了一個(gè)文件,認(rèn)證機(jī)構(gòu)對(duì)此文件用MD5算法產(chǎn)生摘要信息并做好記錄恶迈。若以后A說(shuō)這文件不是他寫(xiě)的涩金,權(quán)威機(jī)構(gòu)只需對(duì)此文件重新產(chǎn)生摘要信息,然后跟記錄在冊(cè)的摘要信息進(jìn)行比對(duì)暇仲,相同的話步做,就證明是A寫(xiě)的了。這就是所謂的“數(shù)字簽名”奈附。
在iOS中的使用
字符串加密:
NSString *message = @"測(cè)試加鹽MD5加密";
const char *cStr = [message UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(cStr, strlen(cStr), result);
NSString *md5 = [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",result[0],result[1],result[2],result[3],result[4],result[5],result[6],result[7],result[8],result[9],result[10],result[11],result[12],result[13],result[14],result[15]];
NSLog(md5);
文件MD5之類(lèi)的 百度一下就有了
Base64算法
Base64編碼原理
如下Base64的索引表全度,字符選用了"A-Z、a-z斥滤、0-9将鸵、+、/" 64個(gè)可打印字符佑颇。數(shù)值代表字符的索引咨堤,這個(gè)是標(biāo)準(zhǔn)Base64協(xié)議規(guī)定的,不能更改漩符。64個(gè)字符用6個(gè)bit位就可以全部表示,一個(gè)字節(jié)有8個(gè)bit 位驱还,剩下兩個(gè)bit就浪費(fèi)掉了嗜暴,這樣就不得不犧牲一部分空間了。這里需要弄明白的就是一個(gè)Base64字符是8個(gè)bit议蟆,但是有效部分只有右邊的6個(gè) bit闷沥,左邊兩個(gè)永遠(yuǎn)是0。
那么怎么用6個(gè)有效bit來(lái)表示傳統(tǒng)字符的8個(gè)bit呢咐容?8和6的最小公倍數(shù) 是24舆逃,也就是說(shuō)3個(gè)傳統(tǒng)字節(jié)可以由4個(gè)Base64字符來(lái)表示,保證有效位數(shù)是一樣的戳粒,這樣就多了1/3的字節(jié)數(shù)來(lái)彌補(bǔ)Base64只有6個(gè)有效bit 的不足路狮。你也可以說(shuō)用兩個(gè)Base64字符也能表示一個(gè)傳統(tǒng)字符,但是采用最小公倍數(shù)的方案其實(shí)是最減少浪費(fèi)的蔚约。結(jié)合下邊的圖比較容易理解奄妨。Man是三個(gè) 字符,一共24個(gè)有效bit苹祟,只好用4個(gè)Base64字符來(lái)湊齊24個(gè)有效位砸抛。紅框表示的是對(duì)應(yīng)的Base64评雌,6個(gè)有效位轉(zhuǎn)化成相應(yīng)的索引值再對(duì)應(yīng) Base64字符表,查出"Man"對(duì)應(yīng)的Base64字符是"TWFU"直焙。說(shuō)到這里有個(gè)原則不知道你發(fā)現(xiàn)了沒(méi)有景东,要轉(zhuǎn)換成Base64的最小單位就是三個(gè)字節(jié),對(duì)一個(gè)字符串來(lái)說(shuō)每次都是三個(gè)字節(jié)三個(gè)字節(jié)的轉(zhuǎn)換奔誓,對(duì)應(yīng)的是Base64的四個(gè)字節(jié)斤吐。這個(gè)搞清楚了其實(shí)就差不多了。
但是轉(zhuǎn)換到最后你發(fā)現(xiàn)不夠三個(gè)字節(jié)了怎么辦呢丝里?愿望終于實(shí)現(xiàn)了曲初,我們可以用兩 個(gè)Base64來(lái)表示一個(gè)字符或用三個(gè)Base64表示兩個(gè)字符,像下圖的A對(duì)應(yīng)的第二個(gè)Base64的二進(jìn)制位只有兩個(gè)杯聚,把后邊的四個(gè)補(bǔ)0就是了臼婆。所以 A對(duì)應(yīng)的Base64字符就是QQ。上邊已經(jīng)說(shuō)過(guò)了幌绍,原則是Base64字符的最小單位是四個(gè)字符一組颁褂,那這才兩個(gè)字 符,后邊補(bǔ)兩個(gè)"="吧傀广。其實(shí)不用"="也不耽誤解碼颁独,之所以用"=",可能是考慮到多段編碼后的Base64字符串拼起來(lái)也不會(huì)引起混淆伪冰。由此可見(jiàn) Base64字符串只可能最后出現(xiàn)一個(gè)或兩個(gè)"="誓酒,中間是不可能出現(xiàn)"="的。下圖中字符"BC"的編碼過(guò)程也是一樣的贮聂。
說(shuō)起B(yǎng)ase64編碼可能有些奇怪靠柑,因?yàn)榇蠖鄶?shù)的編碼都是由字符轉(zhuǎn)化成二進(jìn)制的過(guò)程,而從二進(jìn)制轉(zhuǎn)成字符的過(guò)程稱(chēng)為解碼吓懈。而B(niǎo)ase64的概念就恰好反了歼冰,由二進(jìn)制轉(zhuǎn)到字符稱(chēng)為編碼,由字符到二進(jìn)制稱(chēng)為解碼耻警。
Base64編碼主要用在傳輸隔嫡、存儲(chǔ)、表示二進(jìn)制等領(lǐng)域甘穿,還可以用來(lái)加密腮恩,但是這種加密比較簡(jiǎn)單,只是一眼看上去不知道什么內(nèi)容罷了温兼,當(dāng)然也可以對(duì)Base64的字符序列進(jìn)行定制來(lái)進(jìn)行加密庆揪。
Base64編碼是從二進(jìn)制到字符的過(guò)程,像一些中文字符用不同的編碼轉(zhuǎn)為二 進(jìn)制時(shí)妨托,產(chǎn)生的二進(jìn)制是不一樣的缸榛,所以最終產(chǎn)生的Base64字符也不一樣吝羞。例如"上網(wǎng)"對(duì)應(yīng)utf-8格式的Base64編碼是"5LiK572R", 對(duì)應(yīng)GB2312格式的Base64編碼是"yc/N+A=="内颗。
開(kāi)發(fā)中的安全通信流程
模擬客戶(hù)服務(wù)器安全通信過(guò)程的演變
第一回合:
客戶(hù)和服務(wù)器之間通信
客戶(hù) -> 服務(wù)器:你好
服務(wù)器 -> 客戶(hù):你好钧排,我是服務(wù)器
客戶(hù) -> 服務(wù)器:?均澳?恨溜?
//因?yàn)橄⑹窃诰W(wǎng)絡(luò)上傳輸?shù)模腥丝梢悦俺渥约菏恰胺?wù)器”來(lái)向客戶(hù)發(fā)送信息找前。例如上面的消息可以被“黑客”截獲如下:
客戶(hù) -> 服務(wù)器:你好
服務(wù)器 -> 客戶(hù):你好糟袁,我是服務(wù)器
// “黑客” 在 “客戶(hù)” 和 “服務(wù)器”之間的某個(gè)路由器上截獲 “客戶(hù)” 發(fā)給服務(wù)器的信息,然后自己冒充 “服務(wù)器”
客戶(hù) -> 黑客 :你好
黑客 -> 客戶(hù):你好躺盛,我是服務(wù)器
第一回合 “客戶(hù)” 在接到消息后项戴,并不能肯定這個(gè)消息就是由 “服務(wù)器” 發(fā)出的,某些 “黑客” 也可以冒充“服務(wù)器”發(fā)出這個(gè)消息槽惫。如何確定信息是由“服務(wù)器”發(fā)過(guò)來(lái)的呢周叮?
解決方法: 因?yàn)橹挥蟹?wù)器有私鑰,所以如果只要能夠確認(rèn)對(duì)方有私鑰界斜,那么對(duì)方就是 “服務(wù)器”仿耽。因此通信過(guò)程可以改進(jìn)為如下:
第二回合:
客戶(hù) -> 服務(wù)器:你好
服務(wù)器 -> 客戶(hù) :你好,我是服務(wù)器
客戶(hù) -> 服務(wù)器 :向我證明你就是服務(wù)器
服務(wù)器 -> 客戶(hù) :你好各薇,我是服務(wù)器 {你好项贺,我是服務(wù)器}[私鑰|RSA]
//{} 表示加密后的內(nèi)容,[ | ]表示用什么密鑰和算法進(jìn)行加密峭判,這里表示 RSA 私鑰加密
為了向“客戶(hù)”證明自己是“服務(wù)器”敬扛, “服務(wù)器”把一個(gè)字符串用自己的私鑰加密,把明文和加密后的密文一起發(fā)給“客戶(hù)”朝抖。對(duì)于這里的例子來(lái)說(shuō),就是把字符串 “你好谍珊,我是服務(wù)器”和這個(gè)字符串用私鑰加密后的內(nèi)容 {你好治宣,我是服務(wù)器}[私鑰|RSA] 一起發(fā)給客戶(hù)。
“客戶(hù)”收到信息后砌滞,她用自己持有的公鑰解密密文侮邀,和明文進(jìn)行對(duì)比,如果一致贝润,說(shuō)明信息的確是由服務(wù)器發(fā)過(guò)來(lái)的绊茧。也就是說(shuō)“客戶(hù)”把 {你好,我是服務(wù)器}[私鑰|RSA] 這個(gè)內(nèi)容用公鑰進(jìn)行解密打掘,然后和 “你好华畏,我是服務(wù)器” 對(duì)比鹏秋。因?yàn)橛谩胺?wù)器”用私鑰加密后的內(nèi)容,由并且只能由公鑰進(jìn)行解密亡笑,私鑰只有“服務(wù)器” 持有侣夷,所以如果解密出來(lái)的內(nèi)容是能夠?qū)Φ蒙系模钦f(shuō)明信息一定是從 “服務(wù)器” 發(fā)過(guò)來(lái)的仑乌。
假設(shè)“黑客”想冒充“服務(wù)器”:
黑客 -> 客戶(hù):你好百拓,我是服務(wù)器
客戶(hù) -> 黑客:向我證明你就是服務(wù)器
黑客 -> 客戶(hù):你好,我是服務(wù)器 {你好晰甚,我是服務(wù)器}[衙传??厕九?|RSA] //這里黑客無(wú)法冒充蓖捶,因?yàn)樗恢浪借€,無(wú)法用私鑰加密某個(gè)字符串后發(fā)送給客戶(hù)去驗(yàn)證止剖。
客戶(hù) -> 黑客:腺阳??穿香?亭引?
由于“黑客”沒(méi)有“服務(wù)器”的私鑰,因此它發(fā)送過(guò)去的內(nèi)容皮获,“客戶(hù)”是無(wú)法通過(guò)服務(wù)器的公鑰解密的焙蚓,因此可以認(rèn)定對(duì)方是個(gè)冒牌貨!中斷通信洒宝。
到第二回合結(jié)束购公,“客戶(hù)” 就可以確認(rèn) “服務(wù)器” 的身份了,可以放心和“服務(wù)器”進(jìn)行通信雁歌,同理宏浩,如果客戶(hù)端需要驗(yàn)證也是一樣的道理。
但是這里有一個(gè)問(wèn)題靠瞎,通信的內(nèi)容在網(wǎng)絡(luò)上還是無(wú)法保密比庄。為什么無(wú)法保密呢?通信過(guò)程不是可以用公鑰乏盐、私鑰加密嗎佳窑?其實(shí)用RSA的私鑰和公鑰是不行的,我們來(lái)具體分析下過(guò)程父能,看下面的演示:
第三回合:
客戶(hù) -> 服務(wù)器:你好
服務(wù)器 -> 客戶(hù):你好神凑,我是服務(wù)器
客戶(hù) -> 服務(wù)器:向我證明你就是服務(wù)器
服務(wù)器 -> 客戶(hù):你好,我是服務(wù)器 {你好何吝,我是服務(wù)器}[私鑰|RSA]
//開(kāi)始通信
客戶(hù) -> 服務(wù)器 :{我的帳號(hào)是aaa溉委,密碼是123鹃唯,把我的余額的信息發(fā)給我看看}[公鑰|RSA]
服務(wù)器 -> 客戶(hù):{你的余額是100元}[私鑰|RSA]
注意上面的的信息 {你的余額是100元}[私鑰],這個(gè)是 “服務(wù)器” 用私鑰加密后的內(nèi)容薛躬,但是我們之前說(shuō)了俯渤,公鑰是發(fā)布出去的,因此所有的人都知道公鑰型宝,所以除了 “客戶(hù)”八匠,其它的人也可以用公鑰對(duì) {你的余額是100元}[私鑰]進(jìn)行解密。所以如果 “服務(wù)器” 用私鑰加密發(fā)給“客戶(hù)”趴酣,這個(gè)信息是無(wú)法保密的梨树,因?yàn)橹灰泄€就可以解密這內(nèi)容。然而“服務(wù)器”也不能用公鑰對(duì)發(fā)送的內(nèi)容進(jìn)行加密岖寞,因?yàn)椤翱蛻?hù)”沒(méi)有私鑰抡四,“客戶(hù)”也解密不了。
這樣問(wèn)題就又來(lái)了仗谆,那又如何解決呢指巡?在實(shí)際的應(yīng)用過(guò)程,一般是通過(guò)引入對(duì)稱(chēng)加密來(lái)解決這個(gè)問(wèn)題隶垮,看下面的演示:
第四回合:
客戶(hù) -> 服務(wù)器:你好
服務(wù)器 -> 客戶(hù):你好藻雪,我是服務(wù)器
客戶(hù) -> 服務(wù)器:向我證明你就是服務(wù)器
服務(wù)器 -> 客戶(hù) :你好,我是服務(wù)器 {你好狸吞,我是服務(wù)器}[私鑰|RSA]
客戶(hù) -> 服務(wù)器:{我們后面的通信過(guò)程勉耀,用對(duì)稱(chēng)加密來(lái)進(jìn)行,這里是對(duì)稱(chēng)加密算法和密鑰}[公鑰|RSA] //藍(lán)色字體的部分是對(duì)稱(chēng)加密的算法和密鑰的具體內(nèi)容蹋偏,客戶(hù)把它們發(fā)送給服務(wù)器便斥。
服務(wù)器 -> 客戶(hù):{OK,收到威始!}[密鑰|對(duì)稱(chēng)加密算法]
客戶(hù) -> 服務(wù)器:{我的帳號(hào)是aaa枢纠,密碼是123,把我的余額的信息發(fā)給我看看}[密鑰|對(duì)稱(chēng)加密算法]
服務(wù)器 -> 客戶(hù):{你的余額是100元}[密鑰|對(duì)稱(chēng)加密算法]
在上面的通信過(guò)程中黎棠,“客戶(hù)”在確認(rèn)了“服務(wù)器”的身份后晋渺,“客戶(hù)”自己選擇一個(gè)對(duì)稱(chēng)加密算法和一個(gè)密鑰,把這個(gè)對(duì)稱(chēng)加密算法和密鑰一起用公鑰加密后發(fā)送給“服務(wù)器”葫掉。
注意:由于對(duì)稱(chēng)加密算法和密鑰是用公鑰加密的,就算這個(gè)加密后的內(nèi)容被“黑客”截獲了跟狱,由于沒(méi)有私鑰俭厚,“黑客”也無(wú)從知道對(duì)稱(chēng)加密算法和密鑰的內(nèi)容。
由于是用公鑰加密的驶臊,只有私鑰能夠解密挪挤,這樣就可以保證只有服務(wù)器可以知道對(duì)稱(chēng)加密算法和密鑰叼丑,而其它人不可能知道(這個(gè)對(duì)稱(chēng)加密算法和密鑰是“客戶(hù)”自己選擇的,所以“客戶(hù)”自己當(dāng)然知道如何解密加密)扛门。這樣“服務(wù)器”和“客戶(hù)”就可以用對(duì)稱(chēng)加密算法和密鑰來(lái)加密通信的內(nèi)容了鸠信。
中場(chǎng)休息
我們總結(jié)一下,RSA加密算法在這個(gè)通信過(guò)程中所起到的作用主要有兩個(gè):
加密
因?yàn)樗借€只有“服務(wù)器”擁有论寨,因此“客戶(hù)”可以通過(guò)判斷對(duì)方是否有私鑰來(lái)判斷對(duì)方是否是“服務(wù)器“
簽名
客戶(hù)端通過(guò)RSA的掩護(hù)星立,安全的和服務(wù)器商量好一個(gè)對(duì)稱(chēng)加密算法和密鑰來(lái)保證后面通信過(guò)程內(nèi)容的安全
到這里,“客戶(hù)”就可以確認(rèn)“服務(wù)器”的身份葬凳,并且雙方的通信內(nèi)容可以進(jìn)行加密绰垂,其他人就算截獲了通信內(nèi)容,也無(wú)法解密火焰。的確劲装,好像通信的過(guò)程是比較安全了。
但是這里還留有一個(gè)問(wèn)題昌简,在最開(kāi)始我們就說(shuō)過(guò)占业,“服務(wù)器”要對(duì)外發(fā)布公鑰,那“服務(wù)器”如何把公鑰發(fā)送給“客戶(hù)”呢纯赎?
我們第一反應(yīng)可能會(huì)想到以下的兩個(gè)方法:
a)把公鑰放到互聯(lián)網(wǎng)的某個(gè)地方的一個(gè)下載地址谦疾,事先給“客戶(hù)”去下載。
b)每次和“客戶(hù)”開(kāi)始通信時(shí)址否,“服務(wù)器”把公鑰發(fā)給“客戶(hù)”餐蔬。
但是這個(gè)兩個(gè)方法都有一定的問(wèn)題,
對(duì)于a)方法佑附,“客戶(hù)”無(wú)法確定這個(gè)下載地址是不是“服務(wù)器”發(fā)布的樊诺,你憑什么就相信這個(gè)地址下載的東西就是“服務(wù)器”發(fā)布的而不是別人偽造的呢,萬(wàn)一下載到一個(gè)假的怎么辦音同?另外要所有的“客戶(hù)”都在通信前事先去下載公鑰也很不現(xiàn)實(shí)词爬。
對(duì)于b)方法,也有問(wèn)題权均,因?yàn)槿魏稳硕伎梢宰约荷梢粚?duì)公鑰和私鑰顿膨,他只要向“客戶(hù)”發(fā)送他自己的私鑰就可以冒充“服務(wù)器”了。示意如下:
“客戶(hù)”->“黑客”:你好 //黑客截獲“客戶(hù)”發(fā)給“服務(wù)器”的消息
“黑客”->“客戶(hù)”:你好叽赊,我是服務(wù)器恋沃,這個(gè)是我的公鑰 //黑客自己生成一對(duì)公鑰和私鑰,把公鑰發(fā)給“客戶(hù)”必指,自己保留私鑰
“客戶(hù)”->“黑客”:向我證明你就是服務(wù)器
“黑客”->“客戶(hù)”:你好囊咏,我是服務(wù)器 {你好,我是服務(wù)器}[黑客自己的私鑰|RSA] //客戶(hù)收到“黑客”用私鑰加密的信息后,是可以用“黑客”發(fā)給自己的公鑰解密的梅割,從而會(huì)誤認(rèn)為“黑客”是“服務(wù)器”
因此“黑客”只需要自己生成一對(duì)公鑰和私鑰霜第,然后把公鑰發(fā)送給“客戶(hù)”,自己保留私鑰户辞,這樣由于“客戶(hù)”可以用黑客的公鑰解密黑客的私鑰加密的內(nèi)容泌类,“客戶(hù)”就會(huì)相信“黑客”是“服務(wù)器”,從而導(dǎo)致了安全問(wèn)題底燎。
這里問(wèn)題的根源就在于刃榨,大家都可以生成公鑰、私鑰對(duì)书蚪,無(wú)法確認(rèn)公鑰對(duì)到底是誰(shuí)的喇澡。
如果能夠確定公鑰到底是誰(shuí)的,就不會(huì)有這個(gè)問(wèn)題了殊校。例如晴玖,如果收到“黑客”冒充“服務(wù)器”發(fā)過(guò)來(lái)的公鑰,經(jīng)過(guò)某種檢查为流,如果能夠發(fā)現(xiàn)這個(gè)公鑰不是“服務(wù)器”的就好了呕屎。
數(shù)字證書(shū)
為了解決這個(gè)問(wèn)題,數(shù)字證書(shū)出現(xiàn)了敬察,它可以解決我們上面的問(wèn)題秀睛。先大概看下什么是數(shù)字證書(shū),一個(gè)證書(shū)包含下面的具體內(nèi)容:
- 版本號(hào)莲祸、序列號(hào)(證書(shū)的唯一標(biāo)識(shí))
- 證書(shū)的發(fā)行機(jī)構(gòu) (issuer)
- 證書(shū)的有效期 (valid from蹂安, valid to)
- 公鑰 (public key)
- 證書(shū)所有者名稱(chēng)(subject)
- 簽名所使用的算法
- 指紋以及指紋算法
數(shù)字證書(shū)可以保證數(shù)字證書(shū)里的公鑰確實(shí)是這個(gè)證書(shū)的所有者的,或者證書(shū)可以用來(lái)確認(rèn)對(duì)方的身份锐帜。也就是說(shuō)田盈,我們拿到一個(gè)數(shù)字證書(shū),我們可以判斷出這個(gè)數(shù)字證書(shū)到底是誰(shuí)的〗裳郑現(xiàn)在把前面的通信過(guò)程使用數(shù)字證書(shū)修改為如下:
第五回合:
客戶(hù) -> 服務(wù)器:你好
服務(wù)器 -> 客戶(hù):你好允瞧,我是服務(wù)器,這里是我的數(shù)字證書(shū) //這里用證書(shū)代替了公鑰
客戶(hù) -> 服務(wù)器:向我證明你就是服務(wù)器
服務(wù)器 -> 客戶(hù):你好蛮拔,我是服務(wù)器 {你好述暂,我是服務(wù)器}[私鑰|RSA]
注意,上面第二次通信建炫,“服務(wù)器”把自己的證書(shū)發(fā)給了“客戶(hù)”畦韭,而不是發(fā)送公鑰「氐“客戶(hù)”可以根據(jù)證書(shū)校驗(yàn)這個(gè)證書(shū)到底是不是“服務(wù)器”的艺配,也就是能校驗(yàn)這個(gè)證書(shū)的所有者是不是“服務(wù)器”据过,從而確認(rèn)這個(gè)證書(shū)中的公鑰的確是“服務(wù)器”的。后面的過(guò)程和以前是一樣妒挎,“客戶(hù)”讓“服務(wù)器”證明自己的身份,“服務(wù)器”用私鑰加密一段內(nèi)容連同明文一起發(fā)給“客戶(hù)”西饵,“客戶(hù)”把加密內(nèi)容用數(shù)字證書(shū)中的公鑰解密后和明文對(duì)比酝掩,如果一致,那么對(duì)方就確實(shí)是“服務(wù)器”眷柔,然后雙方協(xié)商一個(gè)對(duì)稱(chēng)加密來(lái)保證通信過(guò)程的安全期虾。到這里,整個(gè)過(guò)程就完整了驯嘱,我們回顧一下:
完整過(guò)程
step1: “客戶(hù)”向服務(wù)端發(fā)送一個(gè)通信請(qǐng)求
客戶(hù) -> 服務(wù)器:你好
step2: “服務(wù)器”向客戶(hù)發(fā)送自己的數(shù)字證書(shū)镶苞。證書(shū)中有一個(gè)公鑰用來(lái)加密信息,私鑰由“服務(wù)器”持有
服務(wù)器 -> 客戶(hù):你好鞠评,我是服務(wù)器茂蚓,這里是我的數(shù)字證書(shū)
step3: “客戶(hù)”收到“服務(wù)器”的證書(shū)后,它會(huì)去驗(yàn)證這個(gè)數(shù)字證書(shū)到底是不是“服務(wù)器”的剃幌,數(shù)字證書(shū)有沒(méi)有什么問(wèn)題聋涨,數(shù)字證書(shū)如果檢查沒(méi)有問(wèn)題,就說(shuō)明數(shù)字證書(shū)中的公鑰確實(shí)是“服務(wù)器”的负乡。檢查數(shù)字證書(shū)后牍白,“客戶(hù)”會(huì)發(fā)送一個(gè)隨機(jī)的字符串給“服務(wù)器”用私鑰去加密,服務(wù)器把加密的結(jié)果返回給“客戶(hù)”抖棘,“客戶(hù)”用公鑰解密這個(gè)返回結(jié)果茂腥,如果解密結(jié)果與之前生成的隨機(jī)字符串一致,那說(shuō)明對(duì)方確實(shí)是私鑰的持有者切省,或者說(shuō)對(duì)方確實(shí)是“服務(wù)器”最岗。
“客戶(hù)”->“服務(wù)器”:向我證明你就是服務(wù)器,這是一個(gè)隨機(jī)字符串 //前面的例子中為了方便解釋?zhuān)玫氖恰澳愫谩钡葍?nèi)容数尿,實(shí)際情況下一般是隨機(jī)生成的一個(gè)字符串仑性。
“服務(wù)器”->“客戶(hù)”:{一個(gè)隨機(jī)字符串}[私鑰|RSA]
step4: 驗(yàn)證“服務(wù)器”的身份后,“客戶(hù)”生成一個(gè)對(duì)稱(chēng)加密算法和密鑰右蹦,用于后面的通信的加密和解密诊杆。這個(gè)對(duì)稱(chēng)加密算法和密鑰,“客戶(hù)”會(huì)用公鑰加密后發(fā)送給“服務(wù)器”何陆,別人截獲了也沒(méi)用晨汹,因?yàn)橹挥小胺?wù)器”手中有可以解密的私鑰。這樣贷盲,后面“服務(wù)器”和“客戶(hù)”就都可以用對(duì)稱(chēng)加密算法來(lái)加密和解密通信內(nèi)容了淘这。
“服務(wù)器”->“客戶(hù)”:{OK剥扣,已經(jīng)收到你發(fā)來(lái)的對(duì)稱(chēng)加密算法和密鑰!有什么可以幫到你的铝穷?}[密鑰|對(duì)稱(chēng)加密算法]
“客戶(hù)”->“服務(wù)器”:{我的帳號(hào)是aaa钠怯,密碼是123,把我的余額的信息發(fā)給我看看}[密鑰|對(duì)稱(chēng)加密算法]
“服務(wù)器”->“客戶(hù)”:{你好曙聂,你的余額是100元}[密鑰|對(duì)稱(chēng)加密算法]
…… //繼續(xù)其它的通信
數(shù)字證書(shū)其他知識(shí)
數(shù)字證書(shū)的內(nèi)容解釋
◆Issuer (證書(shū)的發(fā)布機(jī)構(gòu))
指出是什么機(jī)構(gòu)發(fā)布的這個(gè)證書(shū)晦炊,也就是指明這個(gè)證書(shū)是哪個(gè)公司創(chuàng)建的(只是創(chuàng)建證書(shū),不是指證書(shū)的使用者)宁脊。對(duì)于上面的這個(gè)證書(shū)來(lái)說(shuō)断国,比如"SecureTrust CA"這個(gè)機(jī)構(gòu)。
◆Valid from , Valid to (證書(shū)的有效期)
也就是證書(shū)的有效時(shí)間榆苞,或者說(shuō)證書(shū)的使用期限稳衬。 過(guò)了有效期限,證書(shū)就會(huì)作廢坐漏,不能使用了薄疚。
◆Public key (公鑰)
這個(gè)我們?cè)谇懊娼榻B公鑰密碼體制時(shí)介紹過(guò),公鑰是用來(lái)對(duì)消息進(jìn)行加密的赊琳,第2章的例子中經(jīng)常用到的输涕。這個(gè)數(shù)字證書(shū)的公鑰是2048位的,它的值可以在圖的中間的那個(gè)對(duì)話框中看得到慨畸,是很長(zhǎng)的一串?dāng)?shù)字莱坎。
◆Subject (主題,證書(shū)所有者)
這個(gè)證書(shū)是發(fā)布給誰(shuí)的寸士,或者說(shuō)證書(shū)的所有者檐什,一般是某個(gè)人或者某個(gè)公司名稱(chēng)、機(jī)構(gòu)的名稱(chēng)弱卡、公司網(wǎng)站的網(wǎng)址等乃正。
◆Signature algorithm (簽名所使用的算法)
就是指的這個(gè)數(shù)字證書(shū)的數(shù)字簽名所使用的加密算法,這樣就可以使用證書(shū)發(fā)布機(jī)構(gòu)的證書(shū)里面的公鑰婶博,根據(jù)這個(gè)算法對(duì)指紋進(jìn)行解密瓮具。指紋的加密結(jié)果就是數(shù)字簽名。
◆Thumbprint, Thumbprint algorithm (指紋以及指紋算法)
這個(gè)是用來(lái)保證證書(shū)的完整性的凡人,也就是說(shuō)確保證書(shū)沒(méi)有被修改過(guò)
其原理就是在發(fā)布證書(shū)時(shí)名党,發(fā)布者根據(jù)指紋算法(一個(gè)hash算法)計(jì)算整個(gè)證書(shū)的hash值(指紋)并和證書(shū)放在一起,使用者在打開(kāi)證書(shū)時(shí)挠轴,自己也根據(jù)指紋算法計(jì)算一下證書(shū)的hash值(指紋)传睹,如果和剛開(kāi)始的值對(duì)得上,就說(shuō)明證書(shū)沒(méi)有被修改過(guò)岸晦,因?yàn)樽C書(shū)的內(nèi)容被修改后欧啤,根據(jù)證書(shū)的內(nèi)容計(jì)算的出的hash值(指紋)是會(huì)變化的睛藻。 注意,這個(gè)指紋會(huì)使用"SecureTrust CA"這個(gè)證書(shū)機(jī)構(gòu)的私鑰用簽名算法(Signature algorithm)加密后和證書(shū)放在一起邢隧。
證書(shū)的申請(qǐng)到使用
我們"ABC Company"申請(qǐng)到這個(gè)證書(shū)后店印,我們把證書(shū)投入使用,我們?cè)谕ㄐ胚^(guò)程開(kāi)始時(shí)會(huì)把證書(shū)發(fā)給對(duì)方倒慧,對(duì)方如何檢查這個(gè)證書(shū)的確是合法的并且是我們"ABC Company"公司的證書(shū)呢吱窝?
首先應(yīng)用程序(對(duì)方通信用的程序,例如IE迫靖、OUTLook等)讀取證書(shū)中的Issuer(發(fā)布機(jī)構(gòu))為"SecureTrust CA" ,然后會(huì)在操作系統(tǒng)中受信任的發(fā)布機(jī)構(gòu)的證書(shū)中去找"SecureTrust CA"的證書(shū)兴使,如果找不到系宜,那說(shuō)明證書(shū)的發(fā)布機(jī)構(gòu)是個(gè)水貨發(fā)布機(jī)構(gòu),證書(shū)可能有問(wèn)題发魄,程序會(huì)給出一個(gè)錯(cuò)誤信息盹牧。
如果在系統(tǒng)中找到了"SecureTrust CA"的證書(shū),那么應(yīng)用程序就會(huì)從證書(shū)中取出"SecureTrust CA"的公鑰励幼,然后對(duì)我們"ABC Company"公司的證書(shū)里面的指紋和指紋算法用這個(gè)公鑰進(jìn)行解密汰寓,然后使用這個(gè)指紋算法計(jì)算"ABC Company"證書(shū)的指紋,將這個(gè)計(jì)算的指紋與放在證書(shū)中的指紋對(duì)比苹粟,如果一致有滑,說(shuō)明"ABC Company"的證書(shū)肯定沒(méi)有被修改過(guò)并且證書(shū)是"SecureTrust CA" 發(fā)布的,證書(shū)中的公鑰肯定是"ABC Company"的嵌削。對(duì)方然后就可以放心的使用這個(gè)公鑰和我們"ABC Company"進(jìn)行通信了毛好。
是否可以自己生成證書(shū)
如果數(shù)字證書(shū)只是要在公司內(nèi)部使用,公司可以自己給自己生成一個(gè)證書(shū)苛秕,在公司的所有機(jī)器上把這個(gè)證書(shū)設(shè)置為操作系統(tǒng)信任的證書(shū)發(fā)布機(jī)構(gòu)的證書(shū)(這句話仔細(xì)看清楚肌访,有點(diǎn)繞口),這樣以后公司發(fā)布的證書(shū)在公司內(nèi)部的所有機(jī)器上就可以通過(guò)驗(yàn)證了(在發(fā)布證書(shū)時(shí)艇劫,把這些證書(shū)的Issuer(發(fā)布機(jī)構(gòu))設(shè)置為我們自己的證書(shū)發(fā)布機(jī)構(gòu)的證書(shū)的Subject(主題)就可以了)吼驶。
但是這只限于內(nèi)部應(yīng)用,因?yàn)橹挥形覀児咀约旱臋C(jī)器上設(shè)置了信任我們自己這個(gè)所謂的證書(shū)發(fā)布機(jī)構(gòu)店煞,而其它機(jī)器上并沒(méi)有事先信任我們這個(gè)證書(shū)發(fā)布機(jī)構(gòu)蟹演,所以在其它機(jī)器上,我們發(fā)布的證書(shū)就無(wú)法通過(guò)安全驗(yàn)證顷蟀。
比如 Https 的自簽發(fā)轨帜,但一般都是內(nèi)部使用
其它問(wèn)題
【問(wèn)題1】
上面的通信過(guò)程中說(shuō)到,在檢查完證書(shū)后衩椒,“客戶(hù)”發(fā)送一個(gè)隨機(jī)的字符串給“服務(wù)器”去用私鑰加密蚌父,以便判斷對(duì)方是否真的持有私鑰哮兰。
但是有一個(gè)問(wèn)題,“黑客”也可以發(fā)送一個(gè)字符串給“服務(wù)器”去加密并且得到加密后的內(nèi)容苟弛,這樣對(duì)于“服務(wù)器”來(lái)說(shuō)是不安全的喝滞,因?yàn)楹诳涂梢园l(fā)送一些簡(jiǎn)單的有規(guī)律的字符串給“服務(wù)器”加密,從而尋找加密的規(guī)律膏秫,有可能威脅到私鑰的安全右遭。
所以說(shuō),“服務(wù)器”隨隨便便用私鑰去加密一個(gè)來(lái)路不明的字符串并把結(jié)果發(fā)送給對(duì)方是不安全的缤削。
〖解決方法〗
每次收到“客戶(hù)”發(fā)來(lái)的要加密的的字符串時(shí)窘哈,“服務(wù)器”并不是真正的加密這個(gè)字符串本身,而是把這個(gè)字符串進(jìn)行一個(gè)hash計(jì)算亭敢,加密這個(gè)字符串的hash值(不加密原來(lái)的字符串)后發(fā)送給“客戶(hù)”滚婉,“客戶(hù)”收到后解密這個(gè)hash值并自己計(jì)算字符串的hash值然后進(jìn)行對(duì)比是否一致。
也就是說(shuō)帅刀,“服務(wù)器”不直接加密收到的字符串让腹,而是加密這個(gè)字符串的一個(gè)hash值,這樣就避免了加密那些有規(guī)律的字符串扣溺,從而降低被破解的機(jī)率骇窍。
“客戶(hù)”自己發(fā)送的字符串,因此它自己可以計(jì)算字符串的hash值锥余,然后再把“服務(wù)器”發(fā)送過(guò)來(lái)的加密的hash值和自己計(jì)算的進(jìn)行對(duì)比腹纳,同樣也能確定對(duì)方是否是“服務(wù)器”。
MD5加密
【問(wèn)題2】
在雙方的通信過(guò)程中驱犹,“黑客”可以截獲發(fā)送的加密了的內(nèi)容只估,雖然他無(wú)法解密這個(gè)內(nèi)容,但是他可以搗亂着绷,例如把信息原封不動(dòng)的發(fā)送多次蛔钙,擾亂通信過(guò)程。
〖解決方法〗
可以給通信的內(nèi)容加上一個(gè)序號(hào)或者一個(gè)隨機(jī)的值荠医,如果“客戶(hù)”或者“服務(wù)器”接收到的信息中有之前出現(xiàn)過(guò)的序號(hào)或者隨機(jī)值吁脱,那么說(shuō)明有人在通信過(guò)程中重發(fā)信息內(nèi)容進(jìn)行搗亂,雙方會(huì)立刻停止通信彬向。
有人可能會(huì)問(wèn)兼贡,如果有人一直這么搗亂怎么辦?那不是無(wú)法通信了娃胆? 答案是的確是這樣的遍希,例如有人控制了你連接互聯(lián)網(wǎng)的路由器,他的確可以針對(duì)你里烦。但是一些重要的應(yīng)用凿蒜,例如軍隊(duì)或者政府的內(nèi)部網(wǎng)絡(luò)禁谦,它們都不使用我們平時(shí)使用的公網(wǎng),因此一般人不會(huì)破壞到他們的通信废封。
【問(wèn)題3】
在雙方的通信過(guò)程中州泊,“黑客”除了簡(jiǎn)單的重復(fù)發(fā)送截獲的消息之外,還可以修改截獲后的密文修改后再發(fā)送漂洋,因?yàn)樾薷牡氖敲芪囊T恚m然不能完全控制消息解密后的內(nèi)容,但是仍然會(huì)破壞解密后的密文刽漂。因此發(fā)送過(guò)程如果黑客對(duì)密文進(jìn)行了修改演训,“客戶(hù)”和“服務(wù)器”是無(wú)法判斷密文是否被修改的。雖然不一定能達(dá)到目的贝咙,但是“黑客”可以一直這樣碰碰運(yùn)氣样悟。
〖解決方法〗
在每次發(fā)送信息時(shí),先對(duì)信息的內(nèi)容進(jìn)行一個(gè)hash計(jì)算得出一個(gè)hash值颈畸,將信息的內(nèi)容和這個(gè)hash值一起加密后發(fā)送。接收方在收到后進(jìn)行解密得到明文的內(nèi)容和hash值没讲,然后接收方再自己對(duì)收到信息內(nèi)容做一次hash計(jì)算眯娱,與收到的hash值進(jìn)行對(duì)比看是否匹配,如果匹配就說(shuō)明信息在傳輸過(guò)程中沒(méi)有被修改過(guò)爬凑。如果不匹配說(shuō)明中途有人故意對(duì)加密數(shù)據(jù)進(jìn)行了修改徙缴,立刻中斷通話過(guò)程后做其它處理。
MD5加密