做網(wǎng)站哪個語言強/好項目推薦平臺
1. 引言
????????本周二長城項目在收尾過程中,出現(xiàn)了一個車端無法進行注冊的問題:curl提示證書認證失敗(其實已經(jīng)能確認問題方向了,運維人員去確認證書問題即可)。雖然最終的原因是由于長城運維人員導致的。但是這個過程讓我頗受“感動“。
- 問題出現(xiàn)的當天,運維人員沒有思路,導致現(xiàn)場測試,開發(fā)人員一起調試到晚上10點。
- 當我們咨詢長城人員是否對服務器進行修改時,由于我們并不能明確說明問題點。導致客戶一直不會主動去響應。(屬于雙方的問題)
- 問題定位的不明確。導致項目經(jīng)理問題推進不順利以及消耗我們內部許多資源。(屬于我們技術支持不到位)
????????經(jīng)過此事,我覺得打鐵還需自身硬。雖然問題的原因是因為客戶做了修改。但是我們卻一直不能定位到問題。這就屬于我們的能力問題了。
????????本文,主要是想分享一下該問題的分析思路,以及證書認證相關的知識。希望能對同事們有所幫助。
2. 問題復現(xiàn)過程
問題日志截圖如下:
圖一:車端注冊,平臺反饋失敗
從圖中,我們可以得出,curl 錯誤碼51(認證失敗)。
應對措施:請運維人員進行證書相關的排查。
????????運維人員進行了操作之后,得出結論:并沒有對證書進行修改,并且他自己通過curl 指令,在服務器中是可以訪問成功的。如圖:
圖二:運維人員在服務器上,進行驗證
????????之后就沒有下文,問題就卡住了(當時我的內心是崩潰的)。我用同樣的根證書,客戶端證書,客戶端密鑰,都是無法訪問成功的(拒絕連接)。后來我猜測應該是平臺當時建立了路由規(guī)則,可惜沒辦法驗證了。
圖三:嘗試連接OTA 平臺服務器,卻被拒絕訪問
????????問題掛在這里,過了幾天,客戶終于重視了這個問題,派了對方的運維人員進行查看?;税雮€小時,問題就解決掉了。
圖四:客戶問題定位
????????雖然定位的不一定準確,但是可以確定的是:服務器的根證書有問題。
????????經(jīng)過此事,我花了點時間,查閱網(wǎng)上資料,以及請問通知,總結了https 認證過程中的一些知識點??偨Y之后,感覺之前還是自己知識面窄了,導致浪費了不少的資源。
3. 知識點總結
3.1 ?名詞介紹
對于初學者,建議先了解一下名詞。
名詞 | 解釋 |
證書 | SSL協(xié)議中的證書,其主要功能有兩點。 1.??? 身份驗證 2.??? 數(shù)據(jù)加密傳輸 因此證書中一般包含以下信息:公鑰,持有者信息,證書認證機構的CA信息,證書有效期等。 |
單向認證 | 單項認證是我們平時用的比較多的訪問方式。比如我們訪問百度網(wǎng)站,采用的就是單項認證。瀏覽器只需要認證服務端的合法性即可。 |
雙向認證 | 顧名思義,客戶端不僅要驗證服務器的合法性。服務器也要驗證客戶端的合法性。 |
證書鏈 | 一個證書列表,若對端證書授權于列表中其一,則認為對端證書可信 |
根證書 | 根證書其實就是CA認證中心的一種體現(xiàn)。若本地信任該證書,即表明信任該CA認證中心相關的下屬證書。 |
自簽證書 | 用自己生成的根證書,簽發(fā)證書。但是這種證書對于一般的平臺是不可信的。 |
商簽證書 | 與自簽證書相反。使用的是商業(yè)根證書,簽發(fā)證書。由于商業(yè)根證書一般是被大眾所信任的。根據(jù)證書鏈的原理,簽發(fā)的證書也就被信任。 |
3.2 單向認證和雙向認證
????????我們在不同的項目中,與平臺之間的交互形式是不一樣的。有單向認證和雙向認證。
3.2.1 單向認證
????????單向認證的過程:客戶端從服務端下載服務器端公鑰證書,依據(jù)自己本地證書鏈,進行驗證。若驗證成功,則建立安全通信通道。
服務端需要保存公鑰證書和私鑰兩個文件??蛻舳酥恍枰4?strong>證書鏈即可。
圖五:單向認證流程
3.2.2 雙向認證
????????雙向認證的過程:客戶端除了需要將服務端的公鑰證書下載,與本地證書鏈進行驗證外。還需要將客戶端的公鑰證書上傳到服務端,服務端用自己的根證書進行驗證,等雙方都認證通過了,才開始進行數(shù)據(jù)傳輸。
????????服務端需要保存根證書(用于校驗客戶端證書的合法性),服務器的公鑰證書,服務器的密鑰文件??蛻舳诵枰4?strong>客戶端證書文件,客戶端密鑰文件,客戶端證書鏈。
圖六:雙向認證流程
3.2.3 牛刀小試
當了解認證的流程后,我們可以自己做一個自簽證書流程,以加深印象。從上面的內容中,我們知道需要用到六個證書。
- 服務器端公鑰證書:server.crt
- 服務器端私鑰文件:server.key
- 根證書:root.crt
- 客戶端公鑰證書:client.crt
- 客戶端私鑰文件:client.key
- 客戶端集成證書鏈:client_CA.crt
圖七:證書關系圖
3.2.3.1 生成自簽名根證書
- 創(chuàng)建根證書私鑰。openssl genrsa -out root.key 1024
- 創(chuàng)建根證書請求文件。openssl req -new -out root.csr? -key root.key 。注意:在創(chuàng)建證書請求文件的時候需要注意以下三點,下面生成服務器請求文件和客戶端請求文件均要注意這三點:根證書的Common Name填寫root就可以,所有客戶端和服務器端的證書這個字段需要填寫域名,一定要注意的是,根證書的這個字段和客戶端證書、服務器端證書不能一樣。其他所有字段的填寫,根證書、服務器端證書、客戶端證書需保持一致。最后的密碼可以直接回車跳過。
- 創(chuàng)建根證書。openssl x509 -req -in root.csr -out root.crt -signkey root.key -CAcreateserial -days 3650
得到了有效期為10年的根證書root.crt.我們可以用這個根證書去頒發(fā)服務器證書和客戶端證書。
3.2.3.2????? 生成自簽名服務端證書
- 生成服務器端證書私鑰。openssl genrsa -out server.key 1024
- 生成服務器證書請求文件。openssl req -new -out server.csr -key server.key。證書請求文件中攜帶著公鑰以及用戶信息。但是證書請求文件是未加密的,任何人獲取到之后,都是可以解析其中內容的。
- 生成服務器端公鑰證書。openssl x509 -req -in server.csr -out server.crt -signkey server.key? -CA root.crt -CAkey root.key? -CAcreateserial -days 3650。使用根證書私鑰對證書請求文件內容進行加密,并在證書中添加其它參數(shù)。比如:說明該證書的CA機構(root.crt)。此時root.crt 文件是可以被解析的。但是獲取到的是被加密之后的服務器公鑰+服務器信息。以及簽發(fā)的CA機構(root)。
3.2.3.3????? 生成自簽名客戶端證書
- 生成客戶端的證書密鑰。openssl genrsa -out client.key 1024
- 生成客戶端證書請求文件。openssl req -new -out client.crs -key client.key
- 生成客戶端證書。openssl x509 -req -in client.crs -out client.crt -signkey client.key -CA root.crt -CAkey root.key -CAcreateserial -days 3650
3.3?? 握手過程(單向為例)
通過上面的單向認證以及雙向認證的圖解,我們已經(jīng)有了初步的理解。現(xiàn)在加深一下理解。
- 客戶端向服務器發(fā)起握手請求。該請求中包含了以下內容:
- 客戶端 SSL 協(xié)議的版本號,
- 加密算法的種類,
- ?以及其他服務器和客戶端之間通訊所需要的各種信息。
- ?服務端進行響應,其中包含了:
- SSL 協(xié)議的版本號,
- 加密算法的種類,
- 以及其他相關信息,
- ?同時服務器還將向客戶端傳送自己的證書。
- 客戶端接收到服務端的消息及證書之后,數(shù)字證書就要進行驗證了。流程大致如下:
- 首先將證書進行解密,獲取證書相關信息。
- 判斷證書是否過期;
- 發(fā)行服務器的證書CA是否可靠;(主要查看該CA是否在客戶端的信任列表中)
- 使用發(fā)行者的公鑰機密服務器的數(shù)字簽名。
- 判斷證書上的域名是否和服務器的實際域名相匹配。
- 若以上都通過,則證書合法。并獲取證書中的公鑰。
- 客戶端隨機產(chǎn)生一個用于后面通訊的“對稱密鑰”R,然后用服務器的公鑰對其加密,再發(fā)送給服務器。
- 客戶端向服務器端發(fā)出信息,指明后面的數(shù)據(jù)通訊將使用的步驟 4 中的主密碼為對稱密鑰,同時通知服務器客戶端的握手過程結束。
- 服務器向客戶端發(fā)出信息,指明后面的數(shù)據(jù)通訊將使用的步驟 4 中的主密碼為對稱密鑰,同時通知客戶端服務器端的握手過程結束。
- SSL 的握手部分結束,SSL 安全通道的數(shù)據(jù)通訊開始,客戶和服務器開始使用相同的對稱密鑰進行數(shù)據(jù)通訊,同時進行通訊完整性的檢驗。
4. 思考
若遇上本次問題時,我已掌握上述知識點,我會有什么不同呢?分析:
- 由圖一可知:curl 返回51 錯誤碼。表示客戶對服務器的證書沒有認證通過。
- 其實已經(jīng)將這個排查點通知客戶:客戶端驗證服務器端證書失敗,請問你們是修改服務器證書了嗎?(最初可以直接對客戶拋出這樣的問題,但是由于我們自身不自信,若客戶不理睬,我們也不會去催促他們)。到此,可以將問題拋給客戶了。若更加專業(yè)點,可以進行步驟三。
- 獲取服務器證書內容,將crt 進行解析:openssl x509 -in clientcert.crt -noout -text。分析證書中的內容,找出認證失敗的原因。這樣客戶就沒有理由不理睬了。
后面也遇到了一個證書問題:下載階段,車端無法下載固件包,但是通過瀏覽器進行下載,就可以將固件包下載。
圖8. 車端無法下載固件包
了解了上述的知識點后,我們就可以這樣分析:
瀏覽器訪問是單向認證,并且可以正常下載。(沒有彈出警告),但是我們車端和云端之間采用的是自簽證書。理應服務器的CA不在電腦的信任列表中的。因此,我們可以懷疑客戶采用的證書是商用證書。結果也是如此。
圖9. 客戶的回答:CDN證書錯誤
總結
經(jīng)過此次問題,我由兩點感觸:
- 知識面的提高,對于我們交付組成員而言是比較重要的。
- 對于前線兄弟的支持,目前做的不到位。當問題不清晰,責任不明確時,技術人員不會主動去協(xié)助,導致項目經(jīng)理和測試人員很被動。因此項目中的技術負責人,還是很有必要的。