クライアントプログラムのSSL/TLS対応状況をAPIからチェックする(How’s My SSL?)

昨今、サーバー・クライアント双方において TLS 1.0/1.1を停止し、TLS 1.2 への移行が急速に進んでいます。

TLS1.2への移行の必要性~TLS1.2への有効化が始まる現状の動きとは | グローバルサインブログ

外部サイトに HTTPS 通信しているプログラムが TLS 1.2 に対応しているか確認したいときは、次の URL に GET リクエストしましょう。

https://www.howsmyssl.com/a/check

クライアントの TLS 対応状況を JSON で習得できます。

ブラウザから確認

Chrome Version 75 でアクセスした時の結果は以下の通りです。

{
  "rating": "Probably Okay",
  "tls_version": "TLS 1.3",
  "given_cipher_suites": [
    "TLS_GREASE_IS_THE_WORD_1A",
    "TLS_AES_128_GCM_SHA256",
    "TLS_AES_256_GCM_SHA384",
    "TLS_CHACHA20_POLY1305_SHA256",
    "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
    "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
    "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
    "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
    "TLS_RSA_WITH_AES_128_GCM_SHA256",
    "TLS_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_RSA_WITH_AES_128_CBC_SHA",
    "TLS_RSA_WITH_AES_256_CBC_SHA",
    "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
  ],
  "ephemeral_keys_supported": true,
  "session_ticket_supported": true,
  "tls_compression_supported": false,
  "unknown_cipher_suite_supported": false,
  "beast_vuln": false,
  "able_to_detect_n_minus_one_splitting": false,
  "insecure_cipher_suites": {}
}

総合評価(rating), クライアントが対応している最新の TLS バージョン(tls_version)、クライアントが対応している暗号スイート(given_cipher_suites)、そのうち、セキュアでないもの(insecure_cipher_suites)、といった情報を取得できます。

さすがというべきか、Chrome は TLS 1.3 に対応しており、 セキュアでない暗号スイートは利用していません。

各項目の詳細は次の URL を参照ください。

https://www.howsmyssl.com/s/about.html

コマンドラインプログラムから確認

手元にあった Ubuntu 環境から curl でアクセスしてみます。

$ openssl version
OpenSSL 1.0.1f 6 Jan 2014

$ curl -V
curl 7.35.0 (x86_64-pc-linux-gnu) libcurl/7.35.0 OpenSSL/1.0.1f zlib/1.2.8 libidn/1.28 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP

$ curl https://www.howsmyssl.com/a/check | jq .tls_version
"TLS 1.2"

$ curl https://www.howsmyssl.com/a/check | jq .
{
  "rating": "Bad",
  "tls_version": "TLS 1.2",
  "given_cipher_suites": [
    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
    "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
    "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
    ...
  ],
  "ephemeral_keys_supported": true,
  "session_ticket_supported": false,
  "tls_compression_supported": false,
  "unknown_cipher_suite_supported": false,
  "beast_vuln": false,
  "able_to_detect_n_minus_one_splitting": false,
  "insecure_cipher_suites": {
    "TLS_RSA_WITH_3DES_EDE_CBC_SHA": [
      "uses 3DES which is vulnerable to the Sweet32 attack but was not configured as a fallback in the ciphersuite order"
    ],
    "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA": [
      "uses 3DES which is vulnerable to the Sweet32 attack but was not configured as a fallback in the ciphersuite order"
    ],
    ...
    ]
  }
}

ratingBad なものの、TLS 1.2 はサポートしていますね。

プログラムから確認

アプリケーションから外部サイトにHTTPS通信していることも多いかと思います。

Python の requests ライブラリで HTTPS 通信している場合、次の様にして対応している TLS バージョンを確認できます。

Python 2

$ python2 -m pip install --upgrade requests
$ python2 -c "import requests; print(requests.get('https://www.howsmyssl.com/a/check', verify=False).json()['tls_version'])"

Python 3

$ python3 -m pip install --upgrade requests
$ python3 -c "import requests; print(requests.get('https://www.howsmyssl.com/a/check', verify=False).json()['tls_version'])"

via Python Software Foundation News: Time To Upgrade Your Python: TLS v1.2 Will Soon Be Mandatory

他の言語・ライブラリで HTTPS 通信している場合は、適宜読み替えてください。

"How's My SSL?" を支える技術

今回紹介したサイト("How's My SSL?")・APIを支えるコード(Golang)は、GitHub で公開されています。

GitHub - jmhodges/howsmyssl: The web app running howsmyssl.com

セキュリティチェックサイトが古い規格のまま放置されていると意味をなしませんが、コミットログを見る限り、執筆時点ではメンテされているようです。