一個天朗氣清的週末,決定看一下Composer的原始碼,從安裝檔案先看起,一路順暢,直到遇到了openssl_xxx(),什麼鬼啊這是,突然回想起在系統上安裝軟體的時候經常出現SSL:xxxx的錯誤?他們之間究竟有什麼關係,據說Https和ssl也有關係,媽耶,於是有了這篇科普文。
文章邏輯是按照筆者的思考問題的歷程寫下的,可能有些跳躍,大家多擔待。
文中大部分內容是通過維基百科和百度百科來的,可能自己有部分理解不對,環境大家提出指正。
什麼是OpenSSL
維基百科:OpenSSL是一個開放原始碼的軟體庫包,應用程式可以使用這個包來進行安全通訊,避免竊聽,同時確認另一端連線者的身份。
問題來了
- 怎麼樣就是
安全通訊
了? - 都知道Https比Http安全,但是究竟安全在哪裡?
- SSL是什麼東西?
- SSL和TSL有什麼區別?
接下來,挨個來突破這些問題。
安全通訊
我曾經以為的安全通訊
例子1
小明開發了一個多人部落格網站,所有人都可以在上面發表文章,下載資源
例子2
小黑開發了一個多人部落格網站,只允許登入的使用者在上面發表文章,下載資源
之前我一直以為,使用者認證的過程就是安全通訊的過程。: (
以下是英文版維基百科的定義,中文版的維基百科和百度百科沒有找到相關的定義。
Secure communication is when two entities are communicating and do not want a third party to listen in.
中文:安全通訊是指兩個實體正在通訊並且不希望第三方監聽。
複製程式碼
為了達到上述的目標,就需要**以不易被竊聽或攔截
**的方式進行通訊。
維基百科中還有一段話,附上
Other than spoken face-to-face communication with no possible eavesdropper, it is probably safe to say that no communication is guaranteed secure in this sense, although practical obstacles such as legislation, resources, technical issues (interception and encryption), and the sheer volume of communication serve to limit surveillance.
中文大致意思:除了沒法監聽面對面交流,理論上其他的手段只能限制監聽。
複製程式碼
Tips:有興趣可以閱讀以下維基百科原文 en.wikipedia.org/wiki/Secure… 有一些關於安全的討論。
OK!看完百科的定義,我們可以get一些關鍵詞:監聽
和攔截
,安全通訊,就是圍繞這兩個概念展開的。
竊聽
關於竊聽,有兩個問題。
- 竊聽的定義
- 怎麼做到竊聽
先來看問題1
,計算機中竊聽,通常指的是網路竊聽,接下來,有請萬能的維基百科。
在電腦網路中,竊聽攻擊是在網路層,利用軟體,收集其他電腦送出的封包(Packet),分析其內容,以取得其中的資訊。
複製程式碼
get到關鍵詞,網路層
和Packet
,對於這兩個概念不熟悉的同學,請出門右轉(點選這裡)
網路層提供路由與定址功能,如果在這一層動手腳,那麼源IP+埠/目標IP+埠/Packet我們在這一層中都可以獲取到,解析Packet,就可以獲取到我們所傳送的內容。
再來看問題2
,理論上,大部分的公共wifi都可以被竊聽,運營商的基站,甚至是一些代理。原理也比較簡單,附上一個教程github
攔截
不贅述,附上百科
理論上,我們是無法避免竊聽的,因為我們開發的應用是在應用層,遠在網路層的攻擊,我們是無法避免的。我們能做的,就是即使資料被監聽了,他無法解析出來他想要的資料。
Http與Https
Http與Https的區別就是,Https將Http明文傳輸的協議進行加密,即使資訊被擷取,也無法破解。
Https使用的加密方式是對稱加密
配置過Https的都知道,配置流程中,只需要申請pem和key檔案(CA證照
),在nginx中配置規則,開啟443埠即可。
那麼問題來了:
- 客戶端(瀏覽器/app)是根據什麼規則加密的
(注意:客戶端是沒有任何配置的)
- 伺服器是根據什麼規則解密的
- 怎麼保證中間人竊聽到資料無法解密呢
我們去看Https的維基百科(長文預警
)。
HTTPS的主要思想是在不安全的網路上建立一安全通道,並可在使用適當的加密包和伺服器證照可被驗證且可被信任時,對竊聽和中間人攻擊提供合理的防護。
HTTPS的信任繼承基於預先安裝在瀏覽器中的證照頒發機構(如Symantec、Comodo、GoDaddy和GlobalSign等)(意即“我信任證照頒發機構告訴我應該信任的”)。因此,一個到某網站的HTTPS連線可被信任,當且僅當:
- 使用者相信他們的瀏覽器正確實現了HTTPS且安裝了正確的證照頒發機構;
- 使用者相信證照頒發機構僅信任合法的網站;
- 被訪問的網站提供了一個有效的證照,意即,它是由一個被信任的證照頒發機構簽發的(大部分瀏覽器會對無效的證照發出警告);
- 該證照正確地驗證了被訪問的網站(如,訪問https://example.com時收到了給example.com而不是其它組織的證照);
- 網際網路上相關的節點是值得信任的,或者使用者相信本協議的加密層(TLS或SSL)不能被竊聽者破壞。
複製程式碼
關鍵詞提取:預先安裝在瀏覽器中的證照頒發機構
也就是說中,預先安裝了一個叫證照頒發機構
的東西,想知道這個東西有什麼用,我們就需要了解客戶端的證照頒發機構和伺服器端(CA證照
)的工作原理(SSL握手過程
),以下內容來自百度百科:
- 客戶端的瀏覽器向伺服器傳送客戶端SSL 協議的版本號,加密演算法的種類,產生的隨機數,以及其他伺服器和客戶端之間通訊所需要的各種資訊。
- 伺服器向客戶端傳送SSL 協議的版本號,加密演算法的種類,隨機數以及其他相關資訊,同時伺服器還將向客戶端傳送自己的證照。
- 客戶利用伺服器傳過來的資訊驗證伺服器的合法性,伺服器的合法性包括:證照是否過期,發行伺服器證照的CA 是否可靠,發行者證照的公鑰能否正確解開伺服器證照的“發行者的數字簽名”,伺服器證照上的域名是否和伺服器的實際域名相匹配。如果合法性驗證沒有通過,通訊將斷開;如果合法性驗證通過,將繼續進行第四步
- 使用者端隨機產生一個用於後面通訊的“對稱密碼”,然後用伺服器的公鑰(伺服器的公鑰從步驟②中的伺服器的證照中獲得)對其加密,然後將加密後的“預主密碼”傳給伺服器。
- 如果伺服器要求客戶的身份認證(在握手過程中為可選),使用者可以建立一個隨機數然後對其進行資料簽名,將這個含有簽名的隨機數和客戶自己的證照以及加密過的“預主密碼”一起傳給伺服器。
- 如果伺服器要求客戶的身份認證,伺服器必須檢驗客戶證照和簽名隨機數的合法性,具體的合法性驗證過程包括:客戶的證照使用日期是否有效,為客戶提供證照的CA 是否可靠,發行CA 的公鑰能否正確解開客戶證照的發行CA 的數字簽名,檢查客戶的證照是否在證照廢止列表(CRL)中。檢驗如果沒有通過,通訊立刻中斷;如果驗證通過,伺服器將用自己的私鑰解開加密的“預主密碼”,然後執行一系列步驟來產生主通訊密碼(客戶端也將通過同樣的方法產生相同的主通訊密碼)。
- 伺服器和客戶端用相同的主密碼即“通話密碼”,一個對稱金鑰用於SSL 協議的安全資料通訊的加解密通訊。同時在SSL 通訊過程中還要完成資料通訊的完整性,防止資料通訊中的任何變化。
- 客戶端向伺服器端發出資訊,指明後面的資料通訊將使用的步驟⑦中的主密碼為對稱金鑰,同時通知伺服器客戶端的握手過程結束。
- 伺服器向客戶端發出資訊,指明後面的資料通訊將使用的步驟⑦中的主密碼為對稱金鑰,同時通知客戶端伺服器端的握手過程結束。
- SSL 的握手部分結束,SSL 安全通道的資料通訊開始,客戶和伺服器開始使用相同的對稱金鑰進行資料通訊,同時進行通訊完整性的檢驗。
感嘆一聲,大寫的NB!!!
不理解上述步驟的,看一下我的簡化版(C客戶端,S伺服器
):
- C端與S端驗證對方證照的合法性
- C端產生一個
隨機數1
,用S端公匙加密,產生隨機密碼1
- S端用自己的私匙解析
隨機密碼1
,獲取隨機數1
,此時,C端與S端使用相同的方式對隨機數1
進行運算得到一個通訊密碼
- C端與S端使用相同的通訊密碼對資料進行對稱加密
什麼是SSL
哈哈哈,上面不小心已經解釋過SSL建立連線的過程了。這裡只簡單說幾點:
- SSL是一種安全協議
- SSL針對HTTP進行了特別設計,是的HTTP協議能夠在SSL執行
- HTTPS是HTTP+SSL
- HTTPS執行在443埠,HTTP執行在80埠
- HTTPS需要申請證照
CA
- 在我寫的SSL簡化握手步驟中的123步,為什麼需要這種方式來生成對稱加密的密碼,有以下幾點原因:
- 如果C與S使用預設的密匙,那麼這個密匙一旦被別人獲取到,那麼加密資料就會被解析出來
- 如果使用非堆成加密的方式,如果服務端通過私匙加密的資料被擷取到的話,也是會被加戲出來的,因為公匙是公開的,而且非對稱加密消耗的時間長,並且公匙一旦洩露,也有風險
TSL 與 SSL的區別
SSL是協議層安全性協議 TSL是傳輸層安全性協議
認證方式不同
TSL使用X.509認證(看到這裡,終於知道composer安裝檔案中為什麼大量出現openssl_x509_parse,媽耶
)
SSL認證方式前面已經提到
工作地點不同
TLS工作在傳輸層,應用層協議能透明地執行在TLS協議之上
OpenSSL與php的關係
php中的openssl_xxx()系列的函式,只是php的一個openssl的擴充套件庫,封裝了大量的關於加密解密方面的函式。
openssl是ssl協議的相關實現。
結束。
Life is fantastic!!!