圖文還原HTTPS原理:https://mp.weixin.qq.com/s/3NKOCOeIUF2SGJnY7II9hAlinux
首先簡單的介紹一下 SSL 協議創建鏈接的過程。如圖 1 所示,主要有以下幾個過程:
SSL 身份認證及協商密鑰的過程:程序員
openssl 提供了 SSL 協議的一個開放源代碼的實現,包含三部分:ssl 庫,加解密庫和命令行工具。在命令行工具中 s_client 是一個以 SSL 協議鏈接遠程服務器的客戶端程序,該工具能夠用於測試診斷。雖然 s_client 只提供了一些基礎功能,可是其內部具體實現中使用了 ssl 庫的大部分接口。算法
s_client命令行的語法爲:服務器
openssl s_client [-connect host:port>] [-verify depth] [-cert filename] [-key filename] [-CApath directory] [-CAfile filename][-reconnect] [-pause] [-showcerts] [-debug] [-msg] [-nbio_test] [-state] [-nbio] [-crlf] [-ign_eof] [-quiet]
經常使用參數的具體用途以下:ide
在鏈接 SSL 服務器時最多見的問題就是客戶端認證服務器端身份失敗,有多種緣由形成這些失敗,如下列舉了常見的錯誤並解析瞭如何應用 s_client 進行確診。工具
一、提取服務器的證書:
在 linux 平臺下建立腳本 retrieve-cert.sh 並存入一下清單 1 中的內容。該腳本的輸出內容就是服務器端的 X509 證書通過 Base64 編碼後的內容,執行腳本並將腳本輸出存入文件 server.pem 中。測試
清單 1. 提取證書ui
###usage: retrieve-cert.sh remote.host.name [port] SSLHOST=$1 SSLPORT=${2:-443} echo |\ openssl s_client -connect ${SSLHOST}:${SSLPORT} 2>&1 |\ sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'
二、驗證獲取的證書,在命令行下執行」openss verify server.pem」。
若是證書內容被篡改,那麼執行後的結果如清單 2 所示:編碼
清單 2. 證書驗證失敗加密
[root@wks547385wss openssl]# openssl verify server.pem unable to load certificate 19280:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:947: 19280:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:304:Type=X509 19280:error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:pem_oth.c:82:
不然的話,咱們就能獲得認證經過,結果以下:
清單 3. 證書驗證成功
[root@wks547385wss openssl]# openssl verify server.pem server.pem: OK
1. 使用參數-state檢查是否在握手協議的證書認證時失敗
清單 4. 顯示 SSL 握手協議狀態
[root@wks547385wss openssl]# openssl s_client -connect www6.software.ibm.com:443 -state CONNECTED(00000003) SSL_connect:before/connect initialization SSL_connect:SSLv2/v3 write client hello A SSL_connect:SSLv3 read server hello A depth=1 /C=US/O=Equifax/OU=Equifax Secure Certificate Authority verify error:num=19:self signed certificate in certificate chain verify return:0 SSL_connect:SSLv3 read server certificate A SSL_connect:SSLv3 read server done A SSL_connect:SSLv3 write client key exchange A SSL_connect:SSLv3 write change cipher spec A SSL_connect:SSLv3 write finished A SSL_connect:SSLv3 flush data SSL_connect:SSLv3 read finished A
2. 運用 s_client 參數-showcerts獲取服務器端的根證書,服務器端的證書鏈將會所有顯示出來,在證書鏈的末端就是根證書,保存證書文件爲serverCA.pem 。
清單 5. 獲取服務器端的根證書
[root@wkswss openssl]# openssl s_client -connect www6.software.ibm.com:443 – showcerts … s:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority -----BEGIN CERTIFICATE----- MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y 7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 -----END CERTIFICATE-----
3. 運用 s_client 參數-CAfile CA.pem再次鏈接服務器
清單 6. 設定服務器證書文件創建 SSL 鏈接
[root@wkswss openssl]# openssl s_client -CAfile serverCA.pem -connect www6.software.ibm.com:443 -state CONNECTED(00000003) SSL_connect:before/connect initialization SSL_connect:SSLv2/v3 write client hello A SSL_connect:SSLv3 read server hello A depth=1 /C=US/O=Equifax/OU=Equifax Secure Certificate Authority verify return:1 depth=0 /C=US/O=IBM/CN=www6.software.ibm.com verify return:1 SSL_connect:SSLv3 read server certificate A SSL_connect:SSLv3 read server done A SSL_connect:SSLv3 write client key exchange A SSL_connect:SSLv3 write change cipher spec A SSL_connect:SSLv3 write finished A SSL_connect:SSLv3 flush data SSL_connect:SSLv3 read finished A …… SSL-Session: Protocol : TLSv1 Cipher : DES-CBC3-SHA Session-ID: 00365044871540E334826923BF9C531CE659274858585858499C14380000000C Session-ID-ctx: Master-Key: D065F1F2297560F1CD4CCC0D7A58E647CC9F596BCEC545CF90DD54659CB36C53CDAC977E5784C6 A273BA28B486E578B9 Key-Arg : None Krb5 Principal: None Start Time: 1234986898 Timeout : 300 (sec) Verify return code: 0 (ok)
1. 客戶端已經擁有服務器 build.rchland.ibm.com 的根證書rochCA.pem,當客戶端試圖鏈接服務器客戶時,對服務器的證書認證卻不能經過。
清單 7. 認證失敗
[root@wks547385wss openssl]# openssl s_client -CAfile roch.pem -state -connect build.rchland.ibm.com:443 CONNECTED(00000003) SSL_connect:before/connect initialization SSL_connect:SSLv2/v3 write client hello A SSL_connect:SSLv3 read server hello A depth=0 /serialNumber=93e352/CN=rch-fw-1a.rchland.ibm.com/unstructuredName= rch-fw-1a.rchland.ibm.com verify error:num=18:self signed certificate verify return:1 depth=0 /serialNumber=93e352/CN=rch-fw-1a.rchland.ibm.com/unstructuredName= rch-fw-1a.rchland.ibm.com verify return:1 SSL_connect:SSLv3 read server certificate A SSL_connect:SSLv3 read server done A SSL_connect:SSLv3 write client key exchange A SSL_connect:SSLv3 write change cipher spec A SSL_connect:SSLv3 write finished A SSL_connect:SSLv3 flush data SSL_connect:SSLv3 read finished A …
2. 使用x509工具,查看根證書的具體內容,特別是證書籤發者和持有者的身份,如清單 10 所示。
清單 8. 解碼根證書
[root@wks547385wss openssl]# openssl x509 -text -in roch.pem Certificate: Data: Version: 3 (0x2) Serial Number: 903804111 (0x35def4cf) Signature Algorithm: sha1WithRSAEncryption Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority Validity Not Before: Aug 22 16:41:51 1998 GMT Not After : Aug 22 16:41:51 2018 GMT Subject: C=US, O=Equifax, OU=Equifax Secure Certificate Authority Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit)
有了上述的證書籤發者信息後,咱們的問題就迎刃而解了,客戶端收到了來自防火牆的證書,該證書和防火牆後面的服務器的數字證書來自不一樣的簽發者。
openssl 提供的 ssl 庫被普遍的運用的同時,也增長了程序員在診斷通信故障的難度。巧妙的運用 s_client 無疑給程序員帶來了一把利刃,特別是缺少調試工具的環境下,如嵌入式系統。