openssl Tool SSL analyse
應用 openssl 工具進行 SSL 故障分析 當前 SSL 協(xié)議有著廣泛的運用,在 SSL 服務器的身份認證出現(xiàn)問題時,怎樣才能有效快速的找出問題的根源呢?本文結(jié)合 openssl 提供的命令行工
應用 openssl 工具進行 SSL 故障分析 當前 SSL 協(xié)議有著廣泛的運用,在 SSL 服務器的身份認證出現(xiàn)問題時,怎樣才能有效快速的找出問題的根源呢?本文結(jié)合 openssl 提供的命令行工具 s_client,羅列了多種認證失敗的情況,并給出了問題診斷的方法。
SSL 握手協(xié)議
首先簡單的介紹一下 SSL 協(xié)議建立連接的過程。如圖 1 所示,主要有如下幾個過程: 圖 1. SSL 身份認證及協(xié)商密鑰的過程

?
?
? 客戶端發(fā)起請求,包含一個hello 消息,并附上客戶端支持的密碼算法和 SSL 協(xié)議的版本消息以及用于生成密鑰的隨機數(shù)。 服務器收到消息后,服務器端選擇加密壓縮算法并生成服務器端的隨機數(shù),將該信息反饋給客戶端;接著服務器端將自身的數(shù)字證書(在圖 1 中使用了一個 X.509 數(shù)字證書)發(fā)送到客戶端;完成上述動作后后服務器端會發(fā)送“hello done ”消息給客戶端。此外如果服務器需要對客戶端進行身份認證,服務器端還會發(fā)送一個請求客戶端證書的消息。 一旦客戶端收到”hello done ” , 就開始對服務器端的數(shù)字證書進行認證并檢查服務器端選中的算法是可行的。如果服務器要求認證客戶端身份,客戶端還會發(fā)送自己的公鑰證書。
,?
? 如果對服務器的身份認證通過,客戶端會發(fā)起密鑰交換的請求。 服務器端和客戶端根據(jù)先前協(xié)商的算法和交換隨機數(shù)生成對稱密鑰進行后續(xù)的通信。
s_client 簡介
openssl 提供了 SSL 協(xié)議的一個開放源代碼的實現(xiàn),包含三部分:ssl 庫,加解密庫和命令行工具。在命令行工具中 s_client 是一個以 SSL 協(xié)議連接遠程服務器的客戶端程序,該工具可以用于測試診斷。雖然 s_client 只提供了一些基礎(chǔ)功能,但是其內(nèi)部具體實現(xiàn)中使用了 ssl 庫的大部分接口。 s_client命令行的語法為:
清單 1. s_client 參數(shù)
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]
常用參數(shù)的具體用途如下:
?
?
?
?
?
?
? -connect host:port :指定遠程服務器的地址和端口,如果沒有該參數(shù),默認值為 localhost:443 ; -cert filename:若服務器端需要驗證客戶端的身份,通過 -cert 指定客戶端的證書文件。 -key filename:指定私鑰文件; -verify depth:打開服務器證書驗證并定義證書驗證過程中的最大深度。 -showcerts :顯示服務器證書鏈; -CAfile filename:指定用于驗證服務器證書的根證書; -state :打印出 SSL 會話的狀態(tài)。
s_client 在 SSL 握手協(xié)議中的應用
在連接 SSL 服務器時最常見的問題就是客戶端認證服務器端身份失敗,有多種原因造成這些失敗,以下列舉了常見的錯誤并解析了如何應用 s_client 進行確診。
? 服務器的證書在傳輸過程中被篡改
1. 提取服務器的證書:
在 linux 平臺下創(chuàng)建腳本 retrieve-cert.sh 并存入一下清單 2 中的內(nèi)容。該腳本的輸出內(nèi)容就是服務器端的 X509 證書經(jīng)過 Base64 編碼后的內(nèi)容,執(zhí)行腳本并將腳本輸出存入文件 server.pem 中。 清單 2. 提取證書
###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'
,1. 驗證獲取的證書,在命令行下執(zhí)行”openss verify server.pem”。
如果證書內(nèi)容被篡改,那么執(zhí)行后的結(jié)果如清單 4 所示:
清單 4. 證書驗證失敗
[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:
否則的話,我們就能得到認證通過,結(jié)果如下:
清單 5. 證書驗證成功
[root@wks547385wss openssl]# openssl verify server.pem
server.pem: OK
客戶端沒有保存認證服務器端的證書的根證書;
1. 使用參數(shù)-state 檢查是否在握手協(xié)議的證書認證時失敗
清單 6. 顯示 SSL 握手協(xié)議狀態(tài)
[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 參數(shù)-showcerts 獲取服務器端的根證書,服務器端的證書鏈將會全部顯示出來,在證書鏈的末端就是根證書,保存證書文件為serverCA.pem 。
清單 7. 獲取服務器端的根證書
[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 參數(shù)-CAfile CA.pem再次連接服務器
清單 8. 設(shè)定服務器證書文件建立 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)
客戶端擁有認證服務器證書的根證書,但是服務器被防火墻隔離,防火墻在收到來自客戶端的 SSL 連接請
求時返回防火墻的證書。這種情況下的癥狀跟服務器證書被篡改非常相似,但是區(qū)別在于應用上述提及的方法仍然不能定位錯誤。
1. 客戶端已經(jīng)擁有服務器 build.rchland.ibm.com 的根證書rochCA.pem ,當客戶端試圖連接服務器客戶時,對服務器的證書認證卻不能通過。
清單 9. 認證失敗
[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工具,查看根證書的具體內(nèi)容,特別是證書簽發(fā)者和持有者的身份,如清單 10 所示。 清單 10. 解碼根證書
[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)
有了上述的證書簽發(fā)者信息后,我們的問題就迎刃而解了,客戶端收到了來自防火墻的證書,該證書和防火墻后面的服務器的數(shù)字證書來自不同的簽發(fā)者。
結(jié)束語
openssl 提供的 ssl 庫被廣泛的運用的同時,也增加了程序員在診斷通訊故障的難度。巧妙的運用 s_client 無疑給程序員帶來了一把利刃,特別是缺乏調(diào)試工具的環(huán)境下,如嵌入式系統(tǒng)。 參考資料
?
? ?
? ?
?
? 提供了 SSL 協(xié)議的簡介、握手協(xié)議和主要報文格式 公鑰體系架構(gòu)簡介 如果需要了解 X509 證書的細節(jié),查看 使用完全解析 更多了解 openssl 可查閱 在 尋找為 Linux 開發(fā)人員(包括 )準備的更多參考資料,查閱我們 最受歡迎的文章和教程。 在 developerWorks 上查閱所有 和 。