想學習TLS協議最好的方法應該是去看RFC,但如果對安全傳輸協議沒有一些基本認識的人很難一上來就讀懂RFC里面的種種細節和設計原則,所以這里為了能夠進一步去弄懂TLS協議,把一些基本的知識放在這里,算是掃下盲。
1. TLS與SSL的區別:SSL是TLS的前身,TLS做出了一些使其更安全的改進。事實上,在客戶端向服務器發起連接請求時,會附上的所支持的協議版本;這里的協議版本標識了是SSL或TLS(3.1為TLS)
2. TLS在真正傳輸過程中使用對稱加密,因為對稱加密效率更高。而對稱加密所使用的key是在握手過程中使用特定的算法協商出來的。老版本的SSL使用RSA協商算法,需要使用服務器的公鑰來加密傳輸客戶端隨機生成的對稱key。這種方法有一些安全隱患(一個隱患就是攻擊者可以先存儲下來雙方的加密包。如果攻擊者后來獲取了服務器的私鑰,進而就能獲取對稱key,從而破解密文)。最新的Diffie-Hellman算法可以在協商過程中不傳遞任何關於對稱key的信息,因而更加安全。
3. 客戶端使用證書對服務器進行身份驗證。證書一般由其他機構發放,證書會包含證書的公鑰,並會在結尾處對證書內容做哈希並用發放機構自己的私鑰對哈希值做加密(電子簽名)。客戶端可以用證書中發放機構的公鑰對證書結尾的電子簽名做解密,並驗證解密出的哈希值與證書正文的哈希值是否一致,以驗證證書是否確實為所宣稱的發放機構發放。這個驗證發放者的過程可以不斷遞歸直到驗證到的一個可信的發放者,或者電子簽名驗證失敗。現在一般證書的格式都采用X509這個標准。
上面所述的過程只能驗證證書本身的可信性,而不能驗證提供這個證書的服務器實際上持有相關證書。關於如何驗證服務器確實是證書的持有者,可能有兩種方法:
1). 讓服務器用證書中公鑰對應的私鑰加密一段文字,客戶端用證書的公鑰解密這段密文並驗證服務器的私鑰是否對應證書的公鑰(如何防范人在回路?)
2). 驗證證書中的CN與服務器的CN(基本上可以理解為域名)。因為客戶端在發起向的某個服務器的連接過程中,客戶端是知道自己想要連接到的服務器的域名的。而服務器傳回的證書中包含證書被頒發者的信息,這里面就包含了被頒發者的域名。由於證書是由頒發者的私鑰進行簽名加密的,證書的內容被頒發者無法隨意篡改,所以可以通過比對證書中的域名信息來驗證對方是否是某個域名的服務器。
大體就是這幾個關鍵點,以后有時間再補充細節。
參考資料:
https://developer.mozilla.org/en-US/docs/Archive/Security/Introduction_to_SSL
http://chimera.labs.oreilly.com/books/1230000000545/ch04.html#TLS_FORWARD_SECRECY
http://blog.fourthbit.com/2014/12/23/traffic-analysis-of-an-ssl-slash-tls-session (非常詳細解析協議每種message的格式,重點推薦!!)
關於openssl編程:
http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s03.html
http://www.linuxjournal.com/node/5487/print
http://www.ibm.com/developerworks/library/l-openssl/
https://www.cs.utah.edu/~swalton/Documents/Articles/Programming-OpenSSL.pdf
關於session resumption:
http://vincent.bernat.im/en/blog/2011-ssl-session-reuse-rfc5077.html