歡迎您光臨本站 註冊首頁

應用 openssl 工具進行 SSL 故障分析

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  
當前 SSL 協議有著廣泛的運用,在 SSL 伺服器的身份認證出現問題時,怎樣才能有效快速的找出問題的根源呢?本文結合 openssl 提供的命令行工具 s_client,羅列了多種認證失敗的情況,並給出了問題診斷的方法。

SSL 握手協議

首先簡單的介紹一下 SSL 協議建立連接的過程。如圖 1 所示,主要有如下幾個過程:


圖 1. SSL 身份認證及協商密鑰的過程

  • 客戶端發起請求,包含一個hello消息,並附上客戶端支持的密碼演算法和 SSL 協議的版本消息以及用於生成密鑰的隨機數。
  • 伺服器收到消息后,伺服器端選擇加密壓縮演算法並生成伺服器端的隨機數,將該信息反饋給客戶端;接著伺服器端將自身的數字證書(在圖 1 中使用了一個 X.509 數字證書)發送到客戶端;完成上述動作后后伺服器端會發送“hello done”消息給客戶端。此外如果伺服器需要對客戶端進行身份認證,伺服器端還會發送一個請求客戶端證書的消息。
  • 一旦客戶端收到”hello done” , 就開始對伺服器端的數字證書進行認證並檢查伺服器端選中的演算法是可行的。如果伺服器要求認證客戶端身份,客戶端還會發送自己的公鑰證書。
  • 如果對伺服器的身份認證通過,客戶端會發起密鑰交換的請求。
  • 伺服器端和客戶端根據先前協商的演算法和交換隨機數生成對稱密鑰進行後續的通信。




s_client 簡介

openssl 提供了 SSL 協議的一個開放源代碼的實現,包含三部分:ssl 庫,加解密庫和命令行工具。在命令行工具中 s_client 是一個以 SSL 協議連接遠程伺服器的客戶端程序,該工具可以用於測試診斷。雖然 s_client 只提供了一些基礎功能,但是其內部具體實現中使用了 ssl 庫的大部分介面。

s_client命令行的語法為:


清單 1. 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]

常用參數的具體用途如下:

  • -connect host:port :指定遠程伺服器的地址和埠,如果沒有該參數,默認值為 localhost:443 ;
  • -cert filename:若伺服器端需要驗證客戶端的身份,通過 -cert 指定客戶端的證書文件。
  • -key filename:指定私鑰文件;
  • -verify depth:打開伺服器證書驗證並定義證書驗證過程中的最大深度。
  • -showcerts:顯示伺服器證書鏈;
  • -CAfile filename:指定用於驗證伺服器證書的根證書;
  • -state:列印出 SSL 會話的狀態。




s_client 在 SSL 握手協議中的應用

在連接 SSL 伺服器時最常見的問題就是客戶端認證伺服器端身份失敗,有多種原因造成這些失敗,以下列舉了常見的錯誤並解析了如何應用 s_client 進行確診。

  • 伺服器的證書在傳輸過程中被篡改
    1. 提取伺服器的證書:

在 linux 平台下創建腳本 retrieve-cert.sh 並存入一下清單 2 中的內容。該腳本的輸出內容就是伺服器端的 X509 證書經過 Base64 編碼后的內容,執行腳本並將腳本輸出存入文件 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. 驗證獲取的證書,在命令行下執行”openss verify server.pem”。

如果證書內容被篡改,那麼執行后的結果如清單 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:

否則的話,我們就能得到認證通過,結果如下:


清單 5. 證書驗證成功
[root@wks547385wss openssl]# openssl verify server.pem    server.pem: OK

  • 客戶端沒有保存認證伺服器端的證書的根證書;

1. 使用參數-state檢查是否在握手協議的證書認證時失敗


清單 6. 顯示 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 。


清單 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 參數-CAfile CA.pem再次連接伺服器


清單 8. 設定伺服器證書文件建立 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 連接請求時返回防火牆的證書。這種情況下的癥狀跟伺服器證書被篡改非常相似,但是區別在於應用上述提及的方法仍然不能定位錯誤。

1. 客戶端已經擁有伺服器 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工具,查看根證書的具體內容,特別是證書籤發者和持有者的身份,如清單 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)

有了上述的證書籤發者信息后,我們的問題就迎刃而解了,客戶端收到了來自防火牆的證書,該證書和防火牆後面的伺服器的數字證書來自不同的簽發者。





結束語

openssl 提供的 ssl 庫被廣泛的運用的同時,也增加了程序員在診斷通訊故障的難度。巧妙的運用 s_client 無疑給程序員帶來了一把利刃,特別是缺乏調試工具的環境下,如嵌入式系統。(責任編輯:A6)



[火星人 ] 應用 openssl 工具進行 SSL 故障分析已經有2331次圍觀

http://coctec.com/docs/linux/show-post-68930.html