關於SSL的error問題


 今天模擬網頁版微信登錄的時候又碰到一個SSLError的問題

requests.exceptions.SSLError: [Errno 1] _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
解決辦法:https://stackoverflow.com/questions/10667960/python-requests-throwing-up-sslerror

 

 

 

-------------------------------------------------- 

今天碰到一個requests.exceptions.SSLError: EOF occurred in violation of protocol (_ssl.c:749)的問題,查閱stackoverflow,才知道原來是requests在發送請求的時候,會要求ssl的證書,但是我請求的站點可能是數字證書不被信任,所以出現這個錯誤,解決辦法就是加一個屬性

verify=False,可以先簡單的解決問題。
所以,這里又衍生出兩個問題SSL/TLS協議的運行原理,以及為什么證書會不信任
1、首先第一個問題,阮一峰老師的文章寫的很清楚,原文地址:http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html。我就敲一遍,加深印象,==
一、作用
不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文傳播,帶來了三大風險。
(1) 竊聽風險:第三方可以貨值通信內容
(2) 篡改風險:第三方可以修改通信內容
(3) 冒充風險:第三方可以冒充他人身份參與通信
SSL/TLS協議就是為了解決這三大風險而設計的,希望達到
(1) 所有信息都是加密傳播,第三方無法竊聽
(2) 具有校驗機制,一旦被篡改,通信雙方會立刻發現
(3) 具備身份證書,防止身份被冒充
二、歷史
三、基本的運行過程

SSL/TLS基本思路是采用公鑰加密法,也就是說,客戶端先向服務器端所要公鑰,然后用公鑰加密信息,服務器收到密文后,用自己的私鑰解密
但是,這里有兩個問題?
(1)如何保證公鑰不被篡改
解決辦法就是:將公鑰放在數字證書中。只要證書是可信的,公鑰就是可信的
(2)公鑰加密計算量太大,如何減少耗用的時間?
解決的辦法就是:每一個對話(session),客戶端和服務器端都生成一個”對話密鑰“,用它來加密信息,由於“對話密鑰”是對稱加密,所以運算速度非常快,而服務器公鑰只用於加密“對話密鑰”本身,這樣就減少了加密運算的消耗時間
因此,SSL/TLS協議的基本過程是這樣的
(1)客戶端向服務器端索要並驗證公鑰
(2)雙方協商生成“對話密鑰”
(3)雙方采用“對話密鑰”進行加密通信
上面過程的前兩步,又稱為“握手階段”
四、握手階段的詳細過程

 

“握手階段”涉及四次通信,一個個分開來看,需要注意的是,“握手階段”的所有通信都是明文的
4.1、客戶端發出請求
首先。客戶端(通常是瀏覽器)先向服務器發出加密通信的請求,這被叫做clienthello請求
在這一步,客戶端主要向服務器提供以下信息
(1)支持的協議版本,比如TLS 1.0版
(2)一個客戶端生成的隨機數,稍后用於生成“對話密鑰”
(3)支持的加密方法,比如RSA公鑰加密
(4)支持的壓縮方法
這里需要注意的是,客戶端發送的信息之中不包括服務器的域名,也就是說,理論上服務器只能包含一個網站,否則會分不清應該向客戶端提供哪一個網站的數字證書。這就是為什么同城一台服務器只能有一張數字證書的原因
對於虛擬主機的用戶來說,這很不方便。06年,TLS協議加入了一個Server Name Indication擴展,允許客戶端向服務器提供它所請求的域名
4.2 服務器回應

服務器收到客戶端請求后,向客戶端發出回應,這叫做severhello.服務器的回應包含以下內容
(1)確認使用的加密通信協議版本,比如TLS 1.0版本。如果瀏覽器與服務器支持的版本不一致,服務器關閉加密通信
(2)一個服務器生成的隨機數,稍后用於生成“對話密鑰
(3)確認使用的加密方法,比如RSA公鑰加密
(4)服務器證書
除了上面的這些信息,如果服務器需要確認客戶端的身份,就會再包含一項請求,要求客戶端提供“客戶端證書”,比如,金融機構往往只允許認證客戶連入自己的網絡,就會向正式客戶提供USB密鑰,里面就包含了一張客戶端證書
4.3 客戶端回應
客戶端收到服務器回應以后,首先驗證服務器證書。如果證書不是可信機構頒布、或者證書中的域名與實際域名不一致、或者證書已經過期,就會向訪問者顯示一個警告。由其選擇是否還要繼續通信
如果證書沒有問題,客戶端就會從證書中取出服務器的公鑰,然后,向服務器發送下面3個信息
(1)一個隨機數,該隨機數用服務器公鑰加密,防止被竊聽
(2)編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發送
(3)客戶端握手結束通知,表示客戶端的握手階段已經結束。這一項同時也是前面發送的所有內容的hash值,用來共服務器校驗
上面第一項的隨機數,是整個握手階段出現的第三個隨機數。又稱為“pre master key”。有了它以后,客戶端和服務器就同時有了三個隨機數,接着雙方就用事先商定的加密方法,各自生成本次會話所用的同一把“會話密鑰”
為什么要用三個隨機數來生成“會話密鑰”
不管是客戶端還是服務器,都需要隨機數,這樣生成的密鑰才不會每次都一樣。由於SSL協議中證書是靜態的,因此十分有必要引入一種隨機因素來保證協商出來的密鑰的隨機性
對於RSA密鑰交換算法來說,pre master key 本身就是一個隨機數,再加上hello消息中的隨機,三個隨機數通過一個密鑰導出一個對稱密鑰
pre master的存在在於SSL協議不信任每個主機都能產生完全隨機的隨機數,如果隨機數不隨機,那么pre master secret就有可能被猜出來,那么僅適用pre master secret作為密鑰就不合適了,因此必須引入新的隨機因素,那么客戶端和服務器加上pre master secret
三個隨機數一同生成的密鑰就不容易被猜出了,一個偽隨機數可能完全不隨機,可是是三個偽隨機數就十分接近隨機了,,每增加一個自由度,隨機性增加的可不是一
4.4 服務器的最后回應
服務器收到客戶端的第三個隨機數pre-master key之后,計算生成本次會話所用的“會話密鑰”。然后,向客戶端最后發送下面信息
(1)編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發送
(2)服務器握手結束通知,表示服務器的握手階段已經結束,這一項同時也是前面發送的所有內容的hash值,用來供客戶端校驗
至此,整個握手階段全部結束。接下來。客戶端與服務器進入加密通信,就完全是使用普通的HTTP協議,只不過用“會話加密”加密內容


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM