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

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