使用 OpenSSL 與 cURL 檢查網站伺服器支援哪幾種 Cipher Suites | The Will Will Web

The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

使用 OpenSSL 與 cURL 檢查網站伺服器支援哪幾種 Cipher Suites

當我們從用戶端透過 TLS 協定連接伺服器時,用戶端會準備一組 Cipher Suites 清單給伺服器端,伺服器端必須選用一個強度最高的 Cipher 加密演算法回應,之後才會進行金鑰交換,並開始使用加密連線,確保網路安全。本篇文章將分享如何透過 OpenSSL 查詢有哪些 Cipher Suites 可用,並示範如何透過 cURL 指定特定 Cipher 進行連線與檢查伺服器是否支援特定 Cipher Suite 加密演算法清單。

使用 OpenSSL 查詢有哪些 Ciphers 可用

首先,你要先能夠區分 Cipher SuiteCipher 的差別:

  • Cipher (加密演算法)

    一種負責將 明文 (Plaintext) 透過一系列數學運算,達到將訊息加密密文 (Ciphertext);或將密文訊息解密明文的演算法(algorithm)。

    openssl ciphers -stdname
    
  • Cipher Suite (加密演算法清單)

    代表一系列可用的 Cipher (加密演算法) 清單。

    目前從 Cipher Suite Info 網站可以發現 339 個在 IANA (Internet Assigned Numbers Authority) 登記立案的標準名稱。我們以 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 為例,上面會顯示 IANA name (標準名稱)、OpenSSL nameTLS Version 可供參考。

    參考資料: Mapping OpenSSL cipher suite names to IANA names

    你可以用以下命令查詢目前的 OpenSSL 支援哪些標準名稱(不會所有都支援):

    openssl ciphers
    openssl ciphers -stdname
    openssl ciphers -v
    openssl ciphers -V
    

    上述 4 個命令輸出的內容都差不多,第一個只會顯示 OpenSSL name 而已,使用 -stdname 會額外顯示 IANA name (標準名稱),用 -v 會顯示 OpenSSL name 與相關屬性,而 -V 則會額外顯示 cipher suite 的 Hex code 內容。要用哪個參數,全看你想寫自動化的腳本而定。

    如果想查詢 OpenSSL 目前支援的 Cipher Suite 可以用以下命令篩選出來:

    openssl ciphers -s
    openssl ciphers -s -psk
    openssl ciphers -s -srp
    

    預設 PSK 與 SRP 這兩類 Ciphers 是停用的,需要加上 -psk-srp 才能看到。

當你知道有多少 Cipher Suite 可用之後,我們就可以來設法讀懂 Cipher Suite 的結構。以下我們以 TLS_AES_256_GCM_SHA384 為例:

  1. TLS

    要使用 Cipher Suite 的加密協定,網站通常是 TLS 為主。

  2. AES

    要使用的一種訊息加解密的演算法 (session cipher)

  3. 256

    加密演算法採用的加密金鑰長度 (session encryption key size for cipher) (bits)

  4. GCM

    一種加密的類型 (type of encryption) (cipher-block dependency and additional options)

  5. SHA384

    選用的雜湊演算法 (hash function)

使用 OpenSSL 查詢網站伺服器的所有憑證與 TLS 連接資訊

以下是一段非常實用的 OpenSSL 命令,他不但可以查出伺服器目前所使用的完整憑證資訊,也可以看出整個 TLS 交握的完整過程!

  • OpenSSL 預設會使用 TLS 1.3 (最新版) 進行連線

    openssl s_client -connect www.yahoo.com:443
    

    我們可以跳過憑證的內容,直接顯示 New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256 這段內容,得知本次連線使用的 Cipher Suite:

    New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
    Server public key is 256 bit
    Secure Renegotiation IS NOT supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
    Early data was not sent
    Verify return code: 0 (ok)
    
  • 你也可以指定 TLS 1.2 進行加密連線

    openssl s_client -connect www.yahoo.com:443 -tls1_2
    
    New, TLSv1.2, Cipher is ECDHE-ECDSA-AES128-GCM-SHA256
    Server public key is 256 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
    SSL-Session:
        Protocol  : TLSv1.2
        Cipher    : ECDHE-ECDSA-AES128-GCM-SHA256
        Session-ID: 72CB003E38A8CFC8F9085AFDB1AF26E6F6E11BF44CE7D0074B774E478D876E6F
        Session-ID-ctx:
        Master-Key: A3DA1FB3E11FDAC50929F2D30339BB0F82094B7B503D5E8B018B844F169E7E479B0E11465F16F85E7CD1827A4642D5DB
        PSK identity: None
        PSK identity hint: None
        SRP username: None
        TLS session ticket lifetime hint: 7200 (seconds)
        TLS session ticket:
        0000 - 07 8f f3 fa a9 32 7f 7f-eb 78 07 82 2c 8d 32 49   .....2...x..,.2I
        0010 - 95 ee 44 c7 97 07 e6 f9-96 ba 60 97 14 0a 9b df   ..D.......`.....
        0020 - 05 2c f7 77 17 bf 75 b7-0d d7 d8 20 45 32 67 90   .,.w..u.... E2g.
        0030 - 25 1d 2d 78 f8 0d 73 2b-55 92 bc 81 10 3f d0 29   %.-x..s+U....?.)
        0040 - 14 3b 53 9b 84 6f a8 37-ca 67 5b b8 55 1e e6 04   .;S..o.7.g[.U...
        0050 - 55 85 4c 9d b9 41 7c b3-d8 df 54 9f f4 85 72 89   U.L..A|...T...r.
        0060 - a7 d6 f3 ca 49 79 15 31-f9 4f fd 2a d1 c9 0d 0d   ....Iy.1.O.*....
        0070 - de c4 ed e3 08 b5 00 73-62 1d 4b e1 eb 71 de 83   .......sb.K..q..
        0080 - 13 34 73 92 9b 3d 35 92-01 48 1c 65 69 1f 76 8c   .4s..=5..H.ei.v.
        0090 - 3f af 07 1a c8 4e 70 64-42 a5 24 d0 5a 06 af 1d   ?....NpdB.$.Z...
        00a0 - 89 3c ff f0 e2 e1 4a f4-ff e6 2f e4 83 db f6 94   .<....J.../.....
        00b0 - 00 00 b3 4b 10 60 dd e6-34 e7 63 ac a0 81 9a e6   ...K.`..4.c.....
        00c0 - 61 85 9a 0f 84 3c df 5d-62 9f 09 6b be cc aa d3   a....<.]b..k....
    
        Start Time: 1620800451
        Timeout   : 7200 (sec)
        Verify return code: 0 (ok)
        Extended master secret: yes
    

使用 cURL 指定 Cipher Suite 連接網站伺服器

你必須從 cURL 官方的 SSL Ciphers 網頁得知目前支援哪幾種 Cipher Suites,若以上一段的命令為例,這個 ECDHE-ECDSA-AES128-GCM-SHA256 是有在 cURL 的 TLS v1.2 cipher suites 清單中,因此我們可以指定用來連接遠端的伺服器。

  • 檢測 TLS 連線的資訊

    curl -s -S -v -o /dev/null --no-progress-meter https://www.yahoo.com
    

    從回應的訊息可以看到完整的 TLS 交握過程,並且你也會發現 cURL 預設採用 TLSv1.3 最新版協定進行連線,並使用 TLS_AES_128_GCM_SHA256 這個 Cipher Suite:

    *   Trying 180.222.102.202:443...
    * TCP_NODELAY set
    * Connected to www.yahoo.com (180.222.102.202) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    *   CAfile: /etc/ssl/certs/ca-certificates.crt
      CApath: /etc/ssl/certs
    } [5 bytes data]
    * TLSv1.3 (OUT), TLS handshake, Client hello (1):
    } [512 bytes data]
    * TLSv1.3 (IN), TLS handshake, Server hello (2):
    { [122 bytes data]
    * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
    { [19 bytes data]
    * TLSv1.3 (IN), TLS handshake, Certificate (11):
    { [2908 bytes data]
    * TLSv1.3 (IN), TLS handshake, CERT verify (15):
    { [80 bytes data]
    * TLSv1.3 (IN), TLS handshake, Finished (20):
    { [36 bytes data]
    * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
    } [1 bytes data]
    * TLSv1.3 (OUT), TLS handshake, Finished (20):
    } [36 bytes data]
    * SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
    * ALPN, server accepted to use h2
    
  • 指定最高使用 TLS v1.2 進行連線與指定 Cipher Suite 加密演算法清單

    curl -s -S -v -o /dev/null --no-progress-meter --tls-max 1.2 --ciphers ECDHE-ECDSA-AES128-GCM-SHA256 https://www.yahoo.com
    

    從以下訊息可以看出 ECDHE-ECDSA-AES128-GCM-SHA256 就是連線時選中的 Cipher Suite

    *   Trying 180.222.102.201:443...
    * TCP_NODELAY set
    * Connected to www.yahoo.com (180.222.102.201) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * Cipher selection: ECDHE-ECDSA-AES128-GCM-SHA256
    * successfully set certificate verify locations:
    *   CAfile: /etc/ssl/certs/ca-certificates.crt
      CApath: /etc/ssl/certs
    } [5 bytes data]
    * TLSv1.3 (OUT), TLS handshake, Client hello (1):
    } [512 bytes data]
    * TLSv1.3 (IN), TLS handshake, Server hello (2):
    { [122 bytes data]
    * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
    { [19 bytes data]
    * TLSv1.3 (IN), TLS handshake, Certificate (11):
    { [2908 bytes data]
    * TLSv1.3 (IN), TLS handshake, CERT verify (15):
    { [79 bytes data]
    * TLSv1.3 (IN), TLS handshake, Finished (20):
    { [36 bytes data]
    * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
    } [1 bytes data]
    * TLSv1.3 (OUT), TLS handshake, Finished (20):
    } [36 bytes data]
    * SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
    * ALPN, server accepted to use h2
    

檢查伺服器是否支援特定 Cipher Suite 加密演算法清單

以下我寫了一段 Bash 腳本,可以從 OpenSSL 取出 Cipher Suites 清單,然後透過 cURL 測試一個網站是否支援該 Cipher Suites,如果有支援,就會顯示 OK 字樣。

  • TLS v1.3

    SUPPORTED_CIPHERS=$(openssl ciphers -s -tls1_3)
    IFS=':' read -r -a SUPPORTED_CIPHERS <<< $SUPPORTED_CIPHERS
    for c in "${SUPPORTED_CIPHERS[@]}"
    do
        printf -v pad %30s
        cipher=$c$pad
        printf "Checking ${cipher:0:30} ... "
        curl -s -S -o /dev/null --no-progress-meter --tls-max 1.3 --tls13-ciphers $c https://www.yahoo.com
        if [ $? -eq 0 ]; then
            echo OK
        fi
    done
    

    注意: OpenSSL 1.1.1 之後的版本才能使用 --tls13-ciphers 參數指定 TLS v1.3 的 Cipher Suites,舊版請改用 --ciphers 參數。

  • TLS v1.2

    SUPPORTED_CIPHERS=$(openssl ciphers -s -tls1_2)
    IFS=':' read -r -a SUPPORTED_CIPHERS <<< $SUPPORTED_CIPHERS
    for c in "${SUPPORTED_CIPHERS[@]}"
    do
        printf -v pad %30s
        cipher=$c$pad
        printf "Checking ${cipher:0:30} ... "
        curl -s -S -o /dev/null --no-progress-meter --tls-max 1.2 --ciphers $c https://www.yahoo.com
        if [ $? -eq 0 ]; then
            echo OK
        fi
    done
    

    從下圖可以發現,其實 Yahoo 首頁的網站伺服器已經有許多 Cipher Suites 不支援了!

    Cipher Suites Check

相關連結