中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
HTTPS到底是個啥玩意兒?

我們現(xiàn)在經(jīng)常聽說誰誰誰密碼被盜了,誰誰誰信息又被劫持了。其中有一個原因:絕大部分網(wǎng)站用的是http這個明文協(xié)議。你以為很安全的在password框里填了隱藏的密碼,他卻一字一句明明白白的寫到了網(wǎng)絡(luò)上。于是乎好多網(wǎng)站開始從http遷移到https(至少登錄部分)。我也準(zhǔn)備做同樣的事情,因此抽時間和小伙伴tt一起研究了一下https。

剛開始看https的時候,各種頭大。國內(nèi)網(wǎng)上講相關(guān)的資料雖然一大堆,但是大部分是相互的抄,內(nèi)容多而亂,且沒有把事情講清楚。后來查閱了一些外文資料(包括rfc、wikipedia等),讀了JSSE的源代碼以后,基本把這個事情的來龍去脈看懂了大部分,但是涉及到很多很細(xì)節(jié)的東西還是覺得不是完全懂,如有疏漏和錯誤,敬請大家指正和原諒 :-)

這篇文章的目標(biāo):用盡量簡單和有趣的語言,把這個復(fù)雜的東東講述清楚。所以,接下來我打算分成三部分來聊聊我理解的Https:

1、入門篇:主要用通俗的語言講講Https是什么東東,以及他大體的工作方式;

2、技術(shù)篇:結(jié)合抓包工具和源代碼,分析Https的通訊流程和細(xì)節(jié);

3、理論篇:不是特別深入的聊聊一些跟Https相關(guān)的算法。

====入門篇的分割線====

What’s HTTPS?

簡單的說,https就是給http帶了一個安全套,即使別人拿到了信息,也不知道這個里面裝的啥。客戶端(包括browser、手機(jī)app等)和服務(wù)器每次發(fā)http包的時候,都對這個包加個密,讓第三者看到的只是加密后的亂碼(我只想對你說:你猜你猜你猜猜猜),到對端以后再解密。

這個安全套,原來是叫SSL(Secure Sockets Layer),最先是Netscape弄出來的,后來哥們兒完蛋了,就慢慢變了名字,叫TLS(Transport Layer Security Protocol)。具體的區(qū)別可以去wikipedia搜索TLS,他們之間的升級細(xì)節(jié)講述的非常詳細(xì)(這一點(diǎn)百度百科真的差的有點(diǎn)遠(yuǎn)~)。

這個安全套跑在TCP的上層,在TCP連接完成后且HTTP啟動前,協(xié)商一些跟加密相關(guān)的工作,完成協(xié)商之后,就可以對要發(fā)送的http包加密/解密了。

那他到底協(xié)商了些啥呢?其實就是保證安全的幾個問題:

1、服務(wù)器要證明自己是靠譜的、安全的,不然給一個假網(wǎng)站發(fā)加密的密文就跟裸奔沒啥區(qū)別

2、服務(wù)器和客戶端通訊需要的加密算法和加密密鑰

就跟當(dāng)年天地會和韋小寶通信一樣,先要亮出身份,證明自己,然后再拿出暗語的書信。

ComeOn! How TLS works?

第一步,服務(wù)器證明自己是靠譜的。

一個哥們兒XX說他是天地會的。如果你是韋小寶,你會怎么確認(rèn)他的身份呢?

其中有一種方案可能是這樣的:他會說S1是他師傅,如果你知道S1并和他確認(rèn)了,就ok了。如果不認(rèn)識,就繼續(xù)問S1的師傅S2……一直問道陳近南,只要陳近南確認(rèn)了,那就可以證明他了??雌饋砗孟裨O(shè)計模式里面的責(zé)任鏈 XX -> S1 -> S2 -> … -> ROOT

服務(wù)器證明自己也是同樣的邏輯,服務(wù)器S0有一個證書,說我是誰誰誰,這個證書由上級簽發(fā)機(jī)構(gòu)S1核準(zhǔn),如果你本地有這個S1的證書,那驗證一下就可以了。如果沒有,就問S1的簽發(fā)機(jī)構(gòu)S2。直到根的簽發(fā)機(jī)構(gòu)。如果本地認(rèn)證找到了其中任何一級的證書,就認(rèn)為S0是靠譜的。否則就是不靠譜。S0 -> S1 -> S2 -> … -> Root CA

實際上非常像工商局發(fā)的營業(yè)執(zhí)照,你上面有我蓋的紅坨坨才是靠譜的。

上圖就是淘寶的認(rèn)證級聯(lián)關(guān)系。

這些靠譜的證書內(nèi)置在操作系統(tǒng)、jdk等地方(百度或者谷歌上搜索“https數(shù)字證書設(shè)置”相關(guān)內(nèi)容就可以看到)。

此圖就是我本機(jī)證書列表的一部分。

這個就是基本邏輯,說白了,就是找一個我們都公認(rèn)靠譜的人來證實你的靠譜。

第二步,協(xié)商加密算法+密鑰。

加密和摘要算法有很多,常見的比如RSA、AES、DES、MD5、SHA等等。

大家把他們這樣來分:

1、加密/解密算法:能加密同時能反解的,就是加解密算法。按照加解密的密鑰是否一樣,又分為對稱和非對稱算法。比如對稱加密算法:AES、DES;非對稱加密算法:RSA。

2、摘要算法:就是只用來做摘要、簽名、驗證防止被別人篡改,基本不能反解(有可能可以通過碰撞暴力破解)。比如:MD5、SHA。

那服務(wù)器和客戶端接下來就協(xié)商一下,我們要用什么加密解密算法和密鑰防止別人看見,用什么摘要算法,防止別人篡改。

一般來講,對稱加密算法效率會比非對稱高,所以通常選擇對稱加密的AES較多。雙方通過某種方式協(xié)商出一個密鑰,后面就通過這個密鑰和加密算法進(jìn)行加解密。

客戶端發(fā)送一個:“地振高岡,一派溪山千古秀”

服務(wù)端回復(fù)一個:“門朝大海,三河合水萬年流”

整個過程大體就是這樣,后面雙方就開始發(fā)HTTP的加密包,對方解包得到對應(yīng)的HTTP數(shù)據(jù)。

世界一下就清晰了,對嗎?

No No No 其實還是很復(fù)雜滴…… 如果要想了解詳細(xì)的技術(shù)內(nèi)容,就讓我?guī)е憷^續(xù)往下看(你敢不敢跟我來)

===技術(shù)篇的分割線===

工欲善其事,必先利其器

為了做詳細(xì)的分析,我做了幾個準(zhǔn)備工作:

1、裝了一個wireshark,用來抓取網(wǎng)絡(luò)包

2、寫了一個java程序,打開debug運(yùn)行(java -Djavax.net.debug=all TestHttps),用來看交互細(xì)節(jié)

import java.net.URL;

import java.net.URLConnection;

public class TestHttps

{

public static void main(String[] args) throws Exception

{

final URL url = new URL('https://www.taobao.com');

final URLConnection conn = url.openConnection();

conn.connect();

}

}

3、找到openjdk源代碼:http://grepcode.com/

通過前兩個工作可以看到網(wǎng)絡(luò)交互的過程和詳細(xì)的數(shù)據(jù)包,第三個可以用來分析整個流程的代碼。

(注:以下涉及到代碼的分析,都是基于JDK8進(jìn)行的,如果因為版本原因,相關(guān)函數(shù)和代碼行數(shù)對接不上,請大家查找對應(yīng)版本的代碼)

好了,準(zhǔn)備工作做好了,我們開始吧!

抓個包,先看看門道

先給taobao同學(xué)發(fā)個請求吧:curl https://www.taobao.com,看到整個交互過程大體是這樣的(我把tcp三次握手,ACK包等無關(guān)的數(shù)據(jù)包都過濾掉了,只剩TLS相關(guān)的數(shù)據(jù)包):

上圖有幾個交互數(shù)據(jù)都合并到一個TCP包進(jìn)行發(fā)送了,比如漂藍(lán)的那一行(No = 49)的TCP包實際上包含了三個TLS包(Certificate、Server Key Exchange、Server Hello Done),下面分析的時候,我就把這個包展開。

ClientServer
Client Hello ->
<- server="">
<->
<- server="" key="">
<- server="" hello="">
Client Key Exchange ->
Change Cipher Spec ->
Encrypted Handshake Message ->
<- change="" cipher="">
<- encrypted="" handshake="">
Application Data ->
<- application="">
Encrypted Alert ->

上面抓的包全部展開就是這樣的效果。怎么樣,是不是差不多也看了個大概?我來翻譯翻譯吧。

ClientServer
Client Hello你好!
Server Hello嗯,你好!
Certificate我的證書給你,驗證我吧
Server Key Exchange這是我給你的加密密鑰相關(guān)的東東
Server Hello Done好,我說完了
Client Key Exchange這是我給你的加密密鑰相關(guān)的東東
Change Cipher Spec準(zhǔn)備轉(zhuǎn)換成密文了哦
Encrypted Handshake Message%……&*4 (密文思密達(dá))
Change Cipher Spec我也轉(zhuǎn)換密文了
Encrypted Handshake Message#%&……* (密文思密達(dá))
Application Data%&¥&%*……(HTTP密文數(shù)據(jù))
Application Data**……&%(HTTP密文數(shù)據(jù))
Encrypted Alert警告(實際就是說完了,拜拜~)

看起來是不是很簡單呢?

這實際上就是文章一開始,我說的要解決的兩個大問題:

1、認(rèn)證server端的靠譜性

2、交換加密算法和密鑰

具體每個包里面都發(fā)了哪些數(shù)據(jù)?server端靠譜性是如何來證明的?加密算法和密鑰是怎么交換的?接下來讓我一一給你道來。

具體的交互流程和代碼的實現(xiàn)

我們就按命令逐個來分析一下。

C:Client Hello

可以看到發(fā)送了很多數(shù)據(jù),但是最關(guān)鍵的幾個數(shù)據(jù):

1、TLS的版本

2、隨機(jī)數(shù):這個是用來生成最后加密密鑰的影響因子之一,包含兩部分:時間戳(4-Bytes)和隨機(jī)數(shù)(28-Bytes)

3、session-id:用來表明一次會話,第一次建立沒有。如果以前建立過,可以直接帶過去。

4、加密算法套裝列表:客戶端支持的加密-簽名算法的列表,讓服務(wù)器去選擇。

5、壓縮算法:似乎一般都不用

6、擴(kuò)展字段:比如密碼交換算法的參數(shù)、請求主機(jī)的名字等等

這一段的java實現(xiàn),是在sun.security.ssl.HandshakeMessage.ClientHello里面:

S:Server Hello

當(dāng)服務(wù)器收到客戶端的問候以后,立即做出了響應(yīng):

大體內(nèi)容和客戶端差不多,只是把加密算法的套裝列表換成了服務(wù)器選擇支持的具體算法。

通過這一步,客戶端和服務(wù)器就完成了加密和簽名算法的交換。這里的TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256拆分開看就是:TLS協(xié)議,用ECDH密鑰交換算法交換對稱加密密鑰相關(guān)的參數(shù),用RSA算法做簽名,最后使用AES_128_CBC做內(nèi)容的對稱加密,SHA256做摘要。

具體實現(xiàn)在:sun.security.ssl.HandshakeMessage.ServerHello

S:Certificate

這一步很關(guān)鍵,是服務(wù)器給客戶端展示證書的時候。

證書是一個鏈,從最底層一直到最頂層,表示誰誰誰給我認(rèn)證的。翻譯過來就是文章一開始給大家看到的那個東東:

證書一般采用X.509標(biāo)準(zhǔn),后面我會詳細(xì)來講述證書格式和如何級聯(lián)認(rèn)證。X509證書具體實現(xiàn)在:sun.security.x509.X509CertImpl

Certificate消息的實現(xiàn)代碼在:sun.security.ssl.HandshakeMessage.CertificateMsg 里面

S:Server Key Exchange

這個消息是用來發(fā)送密鑰交換算法相關(guān)參數(shù)和數(shù)據(jù)的。這里要提前提一下,就是根據(jù)密鑰交換算法的不同,傳遞的參數(shù)也是不同的。

常用的密鑰交換算法:RSA、DH(Diffie-Hellman)、ECDH(Elliptic curve Diffie–Hellman)

后面會詳細(xì)來講這幾個算法的某幾個,現(xiàn)在就不詳細(xì)走這個分支,只是知道他們可以交換密鑰,有參數(shù)要傳遞即可。

(這里不得不感嘆一句,老外對基礎(chǔ)科學(xué)的研究真的是太深入了,這些算法十分的巧妙。希望有一天中國人也能對基礎(chǔ)科學(xué)做出更多的貢獻(xiàn)~)

可以看到這里用到的是ECDH算法,交換了一些參數(shù),對數(shù)據(jù)做了簽名,防止劫持者篡改。

在Java里,這個消息有多個實現(xiàn),分別代表RSA、DH、ECDH算法,對應(yīng)的類分別是:

sun.security.ssl.HandshakeMessage.ServerKeyExchange

sun.security.ssl.HandshakeMessage.RSA_ServerKeyExchange

sun.security.ssl.HandshakeMessage.DH_ServerKeyExchange

sun.security.ssl.HandshakeMessage.ECDH_ServerKeyExchange

以下是ECDH的實現(xiàn):

S:Server Hello Done

Server要表達(dá)的信息基本表達(dá)完了,把主持人話筒交給客戶端:

對應(yīng)的實現(xiàn):sun.security.ssl.HandshakeMessage.ServerHelloDone

C:Client Key Exchange

這是客戶端對Server Key Exchange的回應(yīng),用于交換密鑰需要的參數(shù)。和服務(wù)器一樣,不同的密鑰交換算法實現(xiàn)是不一樣的,因此需要的參數(shù)也是有差異的。

這里用的是ECDH交換算法。

Java的實現(xiàn)也對應(yīng)的多個,分別是:

sun.security.ssl.RSAClientKeyExchange

sun.security.ssl.DHClientKeyExchange

sun.security.ssl.ECDHClientKeyExchange

以下是ECDH的具體實現(xiàn):

好了,經(jīng)過以上的步驟,Server-Client已經(jīng)將服務(wù)器認(rèn)證的相關(guān)工作做完了,密文函數(shù)&密鑰交換需要的參數(shù)也都相互傳遞了。剩下的,就是各自用一個叫做PRF(Pseudo-Random Function)的算法去生成加密密鑰,具體的這個函數(shù)是一個對多因子多次迭代摘要運(yùn)算等的實現(xiàn),這里姑且就當(dāng)做是一個很簡單的隨機(jī)運(yùn)算函數(shù)吧,比如:key = rand_c + rand_s + C。

到這一步,客戶端和服務(wù)器就完成了密鑰相關(guān)的交換。

有了這個密鑰,接下來,客戶端和服務(wù)器就開始切換交流語言了(用密文開始說悄悄話),他們會各自發(fā)一個命令,說明自己已經(jīng)準(zhǔn)備好,開始切換語言了。

C:Change Cipher Spec

客戶端切換成密文模式

這個在Java里的實現(xiàn)在:sun.security.ssl.Handshaker

C:Finished(Encrypted Handshake Message)

這個包表明握手已經(jīng)完成,并且對之前發(fā)過的數(shù)據(jù)進(jìn)行加密發(fā)送給對方做校驗,防止被篡改。同時也驗證一下,加密算法、密鑰工作是否正常。

具體代碼在:sun.security.ssl.HandshakeMessage.Finished

在收到這兩個消息以后,服務(wù)器也發(fā)出同樣的消息,即:

S:Change Cipher Spec

S:Finished(Encrypted Handshake Message)

噓~~~(此地長出一口氣) 至此,整個身份驗證、加密/解密算法&密鑰的交換都已經(jīng)結(jié)束,剩余的,就是進(jìn)行正常的HTTP請求以及對請求數(shù)據(jù)的加密/解密。

以上這些步驟,都是對于使用ECDH密鑰交換算法、沒有session、不要求驗證客戶端有效性的情況。對于有session的、或者要求驗證客戶端有效性、或者使用其他密鑰交換算法的,請求會有不一樣,具體的可以看看實現(xiàn)代碼,里面都非常詳細(xì)也容易閱讀,具體代碼在:

sun.security.ssl.ClientHandshaker

sun.security.ssl.ServerHandshaker

里面有一個processMessage函數(shù),是用switch...case寫的相關(guān)的狀態(tài)機(jī)。

看看,為了做安全的HTTP請求,需要額外付出多少的代價,來來回回需要多出多少次數(shù)據(jù)交換。

好了,如果還想了解其他更多更詳細(xì)的東東,就繼續(xù)跟我往下走,否則,在這里就可以return了 ^o^

===有點(diǎn)難度的理論分割線===

接下來準(zhǔn)備聊聊關(guān)于x509證書&證書驗證、加解密、簽名、密鑰交換、隨機(jī)的一些算法。由于我自己對這部分沒有專門的研究,只是借這次機(jī)會看了一些資料,所以了解的不是非常深入,可能只能涉及一些皮毛,大家多多諒解和指正。

1、關(guān)于X.509證書&證書驗證

X.509就是一個數(shù)字證書的標(biāo)準(zhǔn),就像工商營業(yè)執(zhí)照一樣,證明你這個網(wǎng)站是合法的。詳細(xì)的可以參見wikipedia和RFC:

https://en.wikipedia.org/wiki/X.509

http://www.ietf.org/rfc/rfc2459.txt

在TLS中使用到了這樣一個證書來進(jìn)行有效性的認(rèn)證。因為不是專業(yè)研究這個的機(jī)構(gòu),我們就不深入去研究這個標(biāo)準(zhǔn),而是看看他的數(shù)據(jù)格式和如何進(jìn)行驗證。

證書的模樣

我們先看看wireshark抓到的包長什么樣:

再看看Java的API文檔給出的比較詳細(xì)的定義:

http://docs.oracle.com/javase/8/docs/api/java/security/cert/X509Certificate.html

可以看出來,整體分為證書和對證書的簽名兩大部分。

證書包含:版本、序號、證書的簽名算法、簽發(fā)者、主題(被簽發(fā)者)、有效期等的信息。

為了方便閱讀,我們直接用chrome來查看證書:

可以看到非常詳細(xì)的信息,包括:被簽發(fā)者的基本信息、簽發(fā)者的基本信息,加密信息和簽名。我們?nèi)绻约河胦penssl做證書的話,都會要求相關(guān)項的填寫。有興趣的同學(xué)可以自己做一個證書試試手 ^_^

證書的驗證

當(dāng)TLS協(xié)議驗證一個網(wǎng)站是否有效的時候,Server會給出一個X509的證書鏈??蛻舳耸盏竭@個證書鏈以后,對證書鏈進(jìn)行驗證,所做的工作如下:

1、用最底端(證書鏈第一個)的證書,去驗證請求的主機(jī)和證書里的是否是一致

2、逐次驗證證書鏈里每張證書的合法性,直到找到一張證書在系統(tǒng)中存在:這一步又包含每張證書是否在不信任名單里、檢查簽名算法、檢查時間是否過期、檢查證書的發(fā)布者和證書鏈的上一級是否匹配、證書鏈的簽名檢查

以上檢查中,大多是按字節(jié)對比,相對比較簡單,相關(guān)代碼參見以下幾個函數(shù)的實現(xiàn):

sun.security.ssl.X509TrustManagerImpl.checkTrusted

sun.security.validator.SimpleValidator.engineValidate

sun.security.x509.X509CertImpl.verify

sun.security.x509.X509CertImpl.checkValidity

不過,其中證書鏈的簽名檢查是一個非常有意思的算法,這個算法我著實研究了一陣兒,還寫了一個簡單的程序去實驗,在這里稍微詳細(xì)講述一下。

我們得到了一個證書鏈,將他擴(kuò)展開成為一個層級關(guān)系:

對于每一級的證書,都是由上一級用私鑰對證書的sha摘要值進(jìn)行簽名(Root一般由自己簽發(fā)),簽名一般使用RSA算法。驗證的時候,用上一級的公鑰對簽名進(jìn)行解密,還原對應(yīng)的摘要值。如下圖:

這里先提前最最最簡單的插入一下RSA算法。RSA是非對稱加密,有一個公鑰(模數(shù)和指數(shù))和一個私鑰。M代表明文消息,C代表密文,n代表公鑰模數(shù),e代表公鑰指數(shù),d代表私鑰。

如果我們用公鑰對明文M加密,私鑰解密,則是為了傳遞信息,對消息進(jìn)行加密;

如果我們用私鑰對明文M加密,公鑰解密,則是為了保證消息是我簽發(fā)的,沒有偽造和篡改。

這里,我們介紹后一種(即防篡改和偽造)。

簽名加密:C = (M ^ d) mod n

簽名解密:M = (C ^ e) mod n

先請不要問我為什么,后面會單獨(dú)講,哈哈哈(是不是很賤)~

好,回歸正題,上一級認(rèn)證機(jī)構(gòu)用私鑰(d)對下一級的證書的SHA數(shù)字簽名(M) 進(jìn)行RSA加密得到密文(C)。而第三方只要用上一級的公鑰(e, n)對這個加密進(jìn)行還原,并能得到相關(guān)的SHA數(shù)字簽名(M),就可以認(rèn)為是經(jīng)過上一級認(rèn)證過的(因為只有他才能簽的出來)。

Come on,我們來實踐一下吧:

下圖淘寶上一級證書的公鑰(這些機(jī)構(gòu)就賣證書就可以賺翻了):n(圖中的256字節(jié)公共密鑰)和 e(圖中的指數(shù))

我們寫一個程序來驗證一下:

因為要用大數(shù)計算,所以用到了Java的大數(shù)類(這是用的最直接暴力的算法,其實還可以有很多優(yōu)化,比如O(n) -> O(lgn),先取模再乘等等)。

最后輸出的結(jié)果如下:

1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420bedfc063c41b62e0438bc8c0fff669de1926b5accfb487bf3fa98b8ff216d650

其中1fff...ff00是PKCS #1 v1.5 標(biāo)準(zhǔn)的前導(dǎo)補(bǔ)位,詳見:http://tools.ietf.org/html/rfc2313#page-9

接下來 303130…0420 是SHA-256摘要算法的標(biāo)識,詳見:http://tools.ietf.org/html/rfc3447#page-43

剩余部分正好32Bytes,是整個證書的SHA-256摘要。

是真的嗎?確認(rèn)那個32Bytes就是SHA-256的摘要么?來吧,我們寫一個程序驗證一下:

這個程序大致的意思,就是截獲X509證書的驗證,輸出對應(yīng)的證書信息。并用SHA-256對整個證書做摘要。得到的信息輸出如下:

======================

cert-count:

3

subject:

CN=*.tmall.com, O='Alibaba (China) Technology Co., Ltd.', L=HangZhou, ST=ZheJiang, C=CN

cert-sign:

3ec0c71903a19be74dca101a01347ac1464c97e6e5be6d3c6677d599938a13b0db7faf2603660d4aec7056c53381b5d24c2bc0217eb78fb734874714025a0f99259c5b765c26cacff0b3c20adc9b57ea7ca63ae6a2c990837473f72c19b1d29ec575f7d7f34041a2eb744ded2dff4a2e2181979dc12f1e7511464d23d1a40b82a683df4a64d84599df0ac5999abb8946d36481cf3159b6f1e07155cf0e8125b17aba962f642e0817a896fd6c83e9e7a9aeaebfcc4adaae4df834cfeebbc95342a731f7252caa2a97796b148fd35a336476b6c23feef94d012dbfe310da3ea372043d1a396580efa7201f0f405401dff00ecd86e0dcd2f0d824b596175cb07b3d

sha-256:

bedfc063c41b62e0438bc8c0fff669de1926b5accfb487bf3fa98b8ff216d650

======================

這個證書簽名以及對證書做的SHA-256摘要,和我們之前所得到的結(jié)果一樣一樣的~~

好了,到此為止,X509證書的格式和驗證基本上也講了一個大概了,真是非常不容易啊(為了寫文章,肚子已經(jīng)餓的咕咕叫了)~

2.關(guān)于RSA算法

仔細(xì)想想,RSA算法在哪些地方被用到了呢?

1、證書簽名的時候(上面剛剛做了驗證,對吧)

2、密鑰交換

為了防止信息被截獲篡改,需要對密鑰交換的參數(shù)做簽名。

所以,RSA算法是一個非常關(guān)鍵的加解密算法。那我們就來簡單聊聊吧~

(最近看RSA,越看越覺得這個算法很有意思~)

注:為了在文本上打印方便,以下采用 ^ 這個符號作為乘方的運(yùn)算符,即2^4代表2的4次方。

來看看他的定義吧,老復(fù)雜了!

1、選兩個超級大的素數(shù):p 和 q

2、把他們乘起來:n = p * q

3、然后把p-1和q-1也乘起來:m = (p - 1) * (q - 1)

4、再找一個和m互質(zhì)的數(shù):e -> gcd(e, m) = 1

5、最后,找一個d,滿足:(e * d) mod m = 1

6、然后公鑰就是(n, e)的組合,私鑰就是(n, d)的組合

……

我的媽,這么復(fù)雜,人都要瘋了,是不是?

為什么要搞這么復(fù)雜呢?

其實用到了幾個原理或者定理或者…… 他們分別是:

1、大數(shù)分解難題

2、費(fèi)馬小定理

3、中國剩余定理

4、擴(kuò)展歐幾里德算法

是不是被嚇蒙了呢?哈哈哈,由于這一篇是講Https的,所以就不詳細(xì)講這幾個原理,簡單表述一下(就算是簡單,也要說很多,也要碼很多的字……)。

首先,RSA建立的一個基本原則就是大數(shù)分解,如果沒有這個原則,就扯淡了。

我們給兩個素數(shù),比如 5 和 11。我們能很容易求出他們的乘積:5 * 11 = 55

當(dāng)然,在這個規(guī)模下,我們也很容易將 55 分解成 5 * 11。

但是,如果這兩個素數(shù)很大呢,比如10的幾百次方。我們還是很容易求出他們的乘積。不過,你再想分解他,就不容易咯~

其次,著名的費(fèi)馬同學(xué),發(fā)明了很多很多定理,其中比較著名的就是費(fèi)馬大小定理,小定理是這么說的:對于一個素數(shù)n和任意的正整數(shù)a,( a ^ ( n - 1 ) ) mod n = 1

我們來試試,比如 n = 5,a = 4, 那么 a ^ ( n - 1 ) = 4 ^ ( 5 - 1 ) = 256,256 mod 5 = 1

很神奇吧!網(wǎng)上可以搜一搜詳細(xì)的證明。

這個公式演化一下,就可以得到a的n次方和a分別對n取模,結(jié)果是一樣的:( a ^ n ) ≡ a (mod n)

比如上面的那個例子:( 4 ^ 5 ) mod 5 = 4 ; 4 mod 5 = 4

那就是說如果n是一個素數(shù),任意一個數(shù)的i次方模n,都會呈現(xiàn)n-1個數(shù)的循環(huán)周期(不一定是最短的周期),比如:

4的1,2,3,4,5,6……次方模5的余數(shù):4 1 4 1 4 1……

如果n是兩個素數(shù)p和q的乘積,那么這個周期會呈現(xiàn) (p -1) * (q - 1)這么長。也就是說,a 和 a的(p - 1) * (q - 1) + 1次方模n,得到的結(jié)果是一樣的。特別的,如果a <>

哈哈哈,繞了那么大一個彎子,最后的意思就是說,我只要知道 ( a ^ ( (p - 1) * (q - 1) + 1) ) mod n的余數(shù),實際上就是知道了a,對吧!

那我只要變個花樣兒就可以。 我先讓m = (p - 1) * (q - 1) ,然后找一個和m互質(zhì)的數(shù)e,再求出一個d,讓 e * d = k * m + 1。這樣,我給一個數(shù)字 T (其中T < n),計算出="" c="(T" ^="" e)="" mod="" n,="" 我拿著c做一個(c="" ^="" d="" )="" mod="" n,于是乎,神奇的一幕發(fā)生了:(c="" ^="" d)="" mod="" n="(" (t="" ^="" e)="" ^="" d="" )="" mod="" n="(" t="" ^="" (e="" *="" d)="" )="" mod="" n="(" t="" ^="" (k="" *="" m="" +="" 1)="" )="" mod="" n="T" mod="" n,因為="" t="">< n="">

舉個例子,我們讓p = 5, q = 7,推算出來 n = 5 * 7 = 35, m = (5 - 1) * (7 - 1) = 24

我們找一個e,比方是11,那么一定可以找到一個d = 35,e * d = 11 * 35 = 385,

( e * d ) mod m = 385 mod 24 = 1

我們選一個數(shù)字T = 18, 計算 C = (T ^ e) mod n = 2

然后 計算 (C ^ d) mod n = 18 = T

以上就是RSA的原理,是不是要清楚一點(diǎn)了呢?

現(xiàn)在還有一個問題沒有解答,就是我們是怎么找出d來的,實際上就是要解一個方程:

( e * x ) mod m = 1 等價于 e * x + m * y = 1,其中x就是d。

這個就是中國剩余定理里面講到的東東,具體實現(xiàn)的時候,用擴(kuò)展輾轉(zhuǎn)相除法(這就是擴(kuò)展歐拉算法)做個迭代就出來了。

補(bǔ)充一點(diǎn),RSA涉及到指數(shù)運(yùn)算,效率會比較低。實際上有很多優(yōu)化的方法,比如O(n) -> O(lgn),先取模再乘,降維到p和q等等,就不在這里細(xì)展開了。

3.最后簡單聊一個密鑰交換的DH算法

我們在之前提到,TLS要做的事情就是兩個:身份校驗 & 加密算法和密鑰協(xié)商。

身份校驗我們前面已經(jīng)比較詳細(xì)的講述過了。加密算法的協(xié)商我們之前也在流程中講述過。剩下關(guān)于密鑰交換和協(xié)商,我們之前輕描淡寫的聊了下。下面稍微詳細(xì)的講述一下。

在密鑰交換的過程中,會用到一個PRF的函數(shù),是”Pseudo-Random Function”這個的簡稱,中間計算過程比較復(fù)雜,有興趣的同學(xué)可以在網(wǎng)上搜索查閱(由于偷懶,我沒有詳細(xì)深入這個函數(shù) ^_^)。

整個密鑰的生成大體如下:

master_secret = PRF(pre_master_secret, 'master secret', ClientHello.random + ServerHello.random)

具體代碼可以參見:

抽象上來講,就是 server和client 根據(jù)Hello時的兩個隨機(jī)數(shù) 加上 客戶端產(chǎn)生的pre_master_secret來產(chǎn)生一個master_secret,最后由這個東東生成需要的MAC(Message Authentication Code)、key等等加密需要東東。

那其中就有一個關(guān)鍵問題,客戶端的pre_master_secret怎么樣告訴服務(wù)器的?

我們可以用之前講過的RSA算法,客戶端通過服務(wù)器公鑰將這個值加密后傳遞給服務(wù)器,服務(wù)器再去解密。也可以通過一個叫做DH(Diffie-Hellman)的算法。維基百科對這個算法講的十分詳細(xì)。

我就簡單翻譯一下:

有兩個哥們兒,Alice和Bob,他們想交換數(shù)據(jù),于是乎也不知道怎么就想出了一個牛逼的算法:

1、取模數(shù) p = 23,底數(shù) g = 5

2、然后Alice想了一個整數(shù)a = 6,發(fā)送給Bob一個數(shù):A = (g ^ a) mod p = (5 ^ 6) % 23 = 8

3、同理,Bob想了一個整數(shù)b = 15,發(fā)送給Alice一個數(shù):B = (g ^ b) mod p = (5 ^ 15) % 23 = 19

4、Alice拿著Bob給的B = 19,計算了一個數(shù):s = (B ^ a) mod p = (19 ^ 6) % 23 = 2

5、Bob也用同樣的方法,算了一下 : s = (A ^ b) mod p = (8 ^ 15) % 23 = 2

就這樣,在不泄露a、b的情況下,他們兩都得到了一個一樣的數(shù)。就這樣,數(shù)據(jù)交換了。。。

其實理論基礎(chǔ)就是: A ^ b ≡ (g ^ a) ^ b ≡ g ^ (a * b) ≡ (g ^ b) ^ a ≡ B ^ a (mod p)

更詳細(xì)的說明,可以看維基百科的解釋。

后來又有一個改進(jìn)的算法ECDH,這里就不詳細(xì)講述了(偷懶了,以后有機(jī)會再補(bǔ)~)

====總結(jié)的分割線====

好了,斷斷續(xù)續(xù)的抽大家睡覺的時間,把這篇文章寫完了(總算沒有當(dāng)太監(jiān))。個人覺得把HTTPS整個的流程、交互的過程做了一個大體的了解。有一部分做的深入些,還有很多算法看了一個一知半解,越是深入?yún)s發(fā)現(xiàn)不懂或者不了解的越多。剩余還有幾個點(diǎn)由于篇幅和時間的原因沒有講到,比如:如何訪篡改、如何防回放攻擊、如何做PRF、交互里面有些擴(kuò)展參數(shù)等,后面準(zhǔn)備再抽時間把這些補(bǔ)全。

由于之前主要是聚焦在常規(guī)算法和互聯(lián)網(wǎng)技術(shù)架構(gòu)方面,對信息相關(guān)的科學(xué)了解不是那么深入。后面準(zhǔn)備把信息論、加解密算法的相關(guān)東西系統(tǒng)性的看下,完了之后分享出來。有興趣的同學(xué)可以關(guān)注我的微信:simplemain

作為一個碼工,就想安安靜靜做做技術(shù)。春天來了,可以有更多的時間聽著優(yōu)美的輕音樂寫更多的東西了。下面這張照片是我2012年4月在山東濟(jì)南拍的春天,4年時間過去了,又把他翻出來,感受一下當(dāng)年的春意盎然。Hello, World!

附:部分參考資料

https://en.wikipedia.org/wiki/Transport_Layer_Security

http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html

http://www-brs.ub.ruhr-uni-bochum.de/netahtml/HSS/Diss/MeyerChristopher/diss.pdf

http://grepcode.com/snapshot/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/

http://drops.wooyun.org/tips/11232

http://tools.ietf.org/html/rfc3447#page-43

http://netsecurity.51cto.com/art/201505/476337_all.htm

x509:

http://download.oracle.com/technetwork/java/javase/6/docs/zh/api/java/security/cert/X509Certificate.html

RSA:

http://blog.csdn.net/starryheavens/article/details/8536238

https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29

Diffie-Hellman:

https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange

http://my.oschina.net/u/1382972/blog/330456

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
流量安全之HTTPS協(xié)議淺析
大型網(wǎng)站的HTTPS實踐(一)
SSL協(xié)議詳解-2
非對稱加密過程詳解(基于RSA非對稱加密算法實現(xiàn))
C語言實現(xiàn)RSA加解密算法
基于Wireshark抓包淺談對HTTPS的理解(TLS、SSL、數(shù)字證書、數(shù)字簽名)
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服