TLS接続における問題は、理解するのが難しい場合があり、実際に送受信されたメッセージが明確でない場合は特に面倒です。 JSSEには組込みのデバッグ機能があり、システム・プロパティjavax.net.debugによってアクティブ化されます。 javax.net.debugシステム・プロパティの詳細は、「デバッグ・ユーティリティ」を参照してください。
この項では、基本的なTLS 1.3ハンドシェークのデバッグ出力の概要を説明します。 TLSプロトコルの詳細は、『RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3』を参照してください。
ノート:
この例では、デフォルトのJSSE X509KeyManagerおよびX509TrustManagerを使用します。これにより、接続時に使用されるキーおよび信頼できる証明書に関するデバッグ情報も出力されます。 JSSEサンプル・コードのClassFileServerおよびSSLSocketClientWithClientAuthサンプル・アプリケーションを使用します。 ClassFileServerは、クライアント認証を必要とできる単純なHTTPSサーバーです。 SSLSocketClientWithClientAuthは、SSLSocketクラスをクライアントとして使用してHTTPリクエストを送信し、HTTPSサーバーからレスポンスを取得する方法を示します。 より簡単にするために、ClassFileServerとSSLSocketClientWithClientAuthの両方が同じホストから実行されます。
次のコマンドは、ClassFileServerアプリケーションをlocalhost (ポート2002)で実行します。
java \ -Djavax.net.ssl.trustStore=/my_home_directory/jssesamples/samples/samplecacerts \ -Djavax.net.ssl.trustStorePassword=changeit \ ClassFileServer 2002 \ /my_home_directory/jssesamples/samples/ \ TLS true
次のコマンドは、SSLSocketClientWithClientAuthアプリケーションをlocalhost、ポート2002で実行します。 アプリケーションが、前のコマンドで起動したHTTPSサーバーに接続します。 HTTPSリクエストをサーバーに送信し、応答を受信します。 このコマンドは、システム・プロパティjavax.net.debugの値をallに設定し、すべてのデバッグを有効にします。
java -Djavax.net.debug=all -Djavax.net.ssl.trustStore=/my_home_directory/jssesamples/samples/samplecacerts SSLSocketClientWithClientAuth localhost 2002 /index.html
デバッグ出力の各行には、次の情報が含まれます。各フィールドは、縦棒(|)で区切られます。
System.getLogger("javax.net.ssl"))System.Logger.Level)Thread.currentThread().getId())Thread.currentThread().getName())システム・プロパティjdk.tls.client.cipherSuitesおよびjdk.tls.server.cipherSuitesの値は、デフォルトで有効な暗号スイートを決定するためにチェックされます。これらのシステム・プロパティの詳細は、「デフォルトの有効な暗号スイートの指定」を参照してください。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:46.990 EDT|SSLContextImpl.java:427|System property jdk.tls.client.cipherSuites is set to 'null' javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.026 EDT|SSLContextImpl.java:427|System property jdk.tls.server.cipherSuites is set to 'null' ...
これらのシステム・プロパティの値はnullであるため、デフォルトで有効な暗号スイートは、SunJSSEプロバイダがデフォルトで有効にする暗号スイートです。Java Cryptography Architecture (JCA) Oracle Providers Documentation for JDK 8のSunJSSEプロバイダを参照してください。
jdk.tls.keyLimitsの値は、アルゴリズムが特定のキー・セットで暗号化できるデータ量の制限を決定するためにチェックされます。「キー・セットで暗号化できるデータ・アルゴリズムの制限量」を参照してください。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.124 EDT|SSLCipher.java:436|jdk.net.keyLimits: entry = AES/GCM/NoPadding KeyUpdate 2^37. AES/GCM/NOPADDING:KEYUPDATE = 137438953472 ...
デバッグ出力には、サポート対象外および無効の暗号化方式群がリストされます。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.150 EDT|SSLContextImpl.java:401|Ignore disabled cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA javax.net.ssl|ALL|01|main|2018-08-18 01:04:47.150 EDT|SSLContextImpl.java:410|Ignore unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.152 EDT|SSLContextImpl.java:401|Ignore disabled cipher suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ...
X509KeyManagerが初期化されます。 「duke」と呼ばれる被認証者のKeyStoreに1つのkeyEntryがあることが検出されます。 このアプリケーションが自身を認証する場合、X509KeyManagerはkeyEntriesのリストで適切な資格証明を検索します。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.224 EDT|SunX509KeyManagerImpl.java:164|found key for : duke (
"certificate" : {
"version" : "v1",
"serial number" : "3B 0A FA 66",
"signature algorithm": "MD5withRSA",
"issuer" : "CN=Duke, OU=Java Software, O="Sun Microsystems, Inc.", L=Cupertino, ST=CA, C=US",
"not before" : "2001-05-22 19:46:46.000 EDT",
"not after" : "2011-05-22 19:46:46.000 EDT",
"subject" : "CN=Duke, OU=Java Software, O="Sun Microsystems, Inc.", L=Cupertino, ST=CA, C=US",
"subject public key" : "RSA"}
)
...
TrustManagerが初期化され、様々な認証局(CA)から複数の証明書がトラストストアで検出されます。 localhostという識別名の自己署名付き証明書も検出されます。 トラストストア内の信頼できる証明書のチェーンに戻る有効なクレデンシャル(証明書)を提示するサーバーは、そのサーバー自身が信頼されます。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.229 EDT|TrustStoreManager.java:112|trustStore is: /my_home_directory/jssesamples/samples/samplecacerts
trustStore type is: pkcs12
trustStore provider is:
the last modified time is: Tue Dec 11 06:43:38 EST 2012
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.229 EDT|TrustStoreManager.java:311|Reload the trust store
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.264 EDT|TrustStoreManager.java:318|Reload trust certs
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.266 EDT|TrustStoreManager.java:323|Reloaded 32 trust certs
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.322 EDT|X509TrustManagerImpl.java:79|adding as trusted certificates (
"certificate" : {
"version" : "v1",
"serial number" : "00 9B 7E 06 49 A3 3E 62 B9 D5 EE 90 48 71 29 EF 57",
"signature algorithm": "SHA1withRSA",
"issuer" : "CN=VeriSign Class 3 Public Primary Certification Authority - G3, OU="(c) 1999 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US",
"not before" : "1999-09-30 20:00:00.000 EDT",
"not after" : "2036-07-16 19:59:59.000 EDT",
"subject" : "CN=VeriSign Class 3 Public Primary Certification Authority - G3, OU="(c) 1999 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US",
"subject public key" : "RSA"},
"certificate" : {
"version" : "v1",
"serial number" : "61 70 CB 49 8C 5F 98 45 29 E7 B0 A6 D9 50 5B 7A",
"signature algorithm": "SHA1withRSA",
"issuer" : "CN=VeriSign Class 2 Public Primary Certification Authority - G3, OU="(c) 1999 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US",
"not before" : "1999-09-30 20:00:00.000 EDT",
"not after" : "2036-07-16 19:59:59.000 EDT",
"subject" : "CN=VeriSign Class 2 Public Primary Certification Authority - G3, OU="(c) 1999 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US",
"subject public key" : "RSA"},
...
"certificate" : {
"version" : "v1",
"serial number" : "41 00 44 46",
"signature algorithm": "MD5withRSA",
"issuer" : "CN=localhost, OU=Widget Development Group, O="Ficticious Widgets, Inc.", L=Sunnyvale, ST=CA, C=US",
"not before" : "2004-07-22 18:48:38.000 EDT",
"not after" : "2011-05-22 18:48:38.000 EDT",
"subject" : "CN=localhost, OU=Widget Development Group, O="Ficticious Widgets, Inc.", L=Sunnyvale, ST=CA, C=US",
"subject public key" : "RSA"},
...
次の例では、その他の初期化コードを実行してから、サーバーに接続します。
javax.net.ssl|ALL|01|main|2018-08-18 01:04:47.326 EDT|SSLContextImpl.java:115|trigger seeding of SecureRandom javax.net.ssl|ALL|01|main|2018-08-18 01:04:47.524 EDT|SSLContextImpl.java:119|done seeding of SecureRandom javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.562 EDT|HandshakeContext.java:291|Ignore unsupported cipher suite: TLS_AES_128_GCM_SHA256 for TLS12 javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.563 EDT|HandshakeContext.java:291|Ignore unsupported cipher suite: TLS_AES_256_GCM_SHA384 for TLS12 javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.577 EDT|HandshakeContext.java:291|Ignore unsupported cipher suite: TLS_AES_128_GCM_SHA256 for TLS11 ...
デバッグ出力には、無効、サポート対象外、または使用不可の拡張および署名アルゴリズムも表示されます。
javax.net.ssl|WARNING|01|main|2018-08-18 01:04:47.695 EDT|ServerNameExtension.java:255|Unable to indicate server name javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.695 EDT|SSLExtensions.java:235|Ignore, context unavailable extension: server_name javax.net.ssl|WARNING|01|main|2018-08-18 01:04:47.703 EDT|SignatureScheme.java:282|Signature algorithm, ed25519, is not supported by the underlying providers javax.net.ssl|WARNING|01|main|2018-08-18 01:04:47.704 EDT|SignatureScheme.java:282|Signature algorithm, ed448, is not supported by the underlying providers javax.net.ssl|ALL|01|main|2018-08-18 01:04:47.724 EDT|SignatureScheme.java:358|Ignore disabled signature sheme: rsa_md5 javax.net.ssl|INFO|01|main|2018-08-18 01:04:47.724 EDT|AlpnExtension.java:161|No available application protocols javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.724 EDT|SSLExtensions.java:235|Ignore, context unavailable extension: application_layer_protocol_negotiation javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.725 EDT|SSLExtensions.java:235|Ignore, context unavailable extension: cookie javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.763 EDT|SSLExtensions.java:235|Ignore, context unavailable extension: renegotiation_info javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.763 EDT|PreSharedKeyExtension.java:606|No session to resume. javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.763 EDT|SSLExtensions.java:235|Ignore, context unavailable extension: pre_shared_key ...
クライアントは、サーバーにClientHelloメッセージを送信します。 このメッセージでは、次の項目を指定します。
クライアント・バージョン: TLS 1.3の場合、この値は固定値TLSv1.2です。TLS 1.3では、このフィールドではなく、supported_versions拡張を使用してプロトコル・バージョンをネゴシエートします
ランダム: 暗号化アルゴリズムの初期化に使用される乱数値
セッションID: 以前のバージョンのTLSは、このIDを使用してセッション再開機能をサポートします
暗号化方式群: クライアントが要求する暗号化方式群のリスト。有効な暗号化方式群に応じて、暗号化方式群名には様々な組合せがあり、一部はTLSv1.3専用、その他はTLSv1.2以前を対象としています
圧縮方法: TLS 1.3の場合は、値0が指定されている必要があります
拡張:
status_request: クライアントがOCSPを要求します(「クライアント主導型OCSPとOCSPステープリング」を参照)
supported_groups: クライアントがキー交換でサポートしている名前付きグループをリストします。 これらの名前付きグループには、楕円曲線(ECDHE)グループと有限フィールド(DHE)グループが含まれます。 ECDHEまたはDHEキー交換を使用している場合、ClientHelloメッセージにはこのメッセージが含まれている必要があります。
ec_point_formats: クライアントが解析可能な楕円曲線のポイント形式をリストします。この例で、クライアントが解析できるのは非圧縮ポイント形式のみです。 その他の形式には、圧縮形式とansiX962_compressed_primeがあります。
署名アルゴリズム: CertificateVerifyメッセージで使用できる署名アルゴリズムをリストします
signature_algorithms_cert: デジタル署名で使用できる署名アルゴリズムをリストします
status_request_v2: クライアントが複数の証明書ステータスのメソッドを指定およびサポートできるようにします。 この拡張はTLS 1.3では非推奨です。
extended_master_secret: TLS 1.2以前では、この拡張を使用して、両方の側が元のプロトコル・バージョンで実行されていたよりも多くのハンドシェーク・トランスクリプトをマスター・シークレットにダイジェストすることを要求します(RFC 7627を参照)。 この拡張は、TLS 1.2ハンドシェークがネゴシエートされる場合に備えて、TLS 1.3ハンドシェークに含まれています。
supported_versions: クライアントでサポートされているTLSバージョンをリストします。 具体的には、クライアントがTLS 1.3を要求する場合、クライアント・バージョン・フィールドの値はTLSv1.2で、この拡張の値はTLSv1.3になります。クライアントがTLS 1.2を要求する場合、クライアント・バージョン・フィールドの値はTLSv1.2で、この拡張は存在しないか、値がTLSv1.3ではなくTLSv1.2になります。
psk_key_exchange_modes: 事前共有キー(PSK)で使用できるキー交換モードをリストします。この例で、クライアントがサポートしているモードは、(EC)DHEを伴うPSKキー確立(psk_dhe_ke)です。 このモードでは、クライアントとサーバーがkey_share拡張の値を提供する必要があります。
key_share: キー交換の暗号化パラメータをリストします。 client_sharesという名前のフィールドに、このリストが格納されています。 このリストの各項目には、2つのフィールド(groupとkey_exchange)があります。 この例には、楕円曲線secp256r1のキー交換情報が含まれています。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.769 EDT|ClientHello.java:633|Produced ClientHello handshake message (
"ClientHello": {
"client version" : "TLSv1.2",
"random" : "64 CF 68 A1 CF AB B1 6F 43 F6 DE 1B 49 49 DE 5A 42 9A 71 DD CB 9A E3 9F 32 00 E8 87 7A 00 DA C6",
"session id" : "02 0D BE 1B A4 5F F2 E8 B6 31 9D A4 EF F3 22 84 C3 58 0B 5C C0 57 0F A5 6D 8A 83 EB DC DA B1 B6",
"cipher suites" : "[TLS_AES_128_GCM_SHA256(0x1301), TLS_AES_256_GCM_SHA384(0x1302), TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384(0xC02C), TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256(0xC02B), TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(0xC030), TLS_RSA_WITH_AES_256_GCM_SHA384(0x009D), TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384(0xC02E), TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384(0xC032), TLS_DHE_RSA_WITH_AES_256_GCM_SHA384(0x009F), TLS_DHE_DSS_WITH_AES_256_GCM_SHA384(0x00A3), TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(0xC02F), TLS_RSA_WITH_AES_128_GCM_SHA256(0x009C), TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256(0xC02D), TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256(0xC031), TLS_DHE_RSA_WITH_AES_128_GCM_SHA256(0x009E), TLS_DHE_DSS_WITH_AES_128_GCM_SHA256(0x00A2), TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384(0xC024), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384(0xC028), TLS_RSA_WITH_AES_256_CBC_SHA256(0x003D), TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384(0xC026), TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384(0xC02A), TLS_DHE_RSA_WITH_AES_256_CBC_SHA256(0x006B), TLS_DHE_DSS_WITH_AES_256_CBC_SHA256(0x006A), TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA(0xC00A), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(0xC014), TLS_RSA_WITH_AES_256_CBC_SHA(0x0035), TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA(0xC005), TLS_ECDH_RSA_WITH_AES_256_CBC_SHA(0xC00F), TLS_DHE_RSA_WITH_AES_256_CBC_SHA(0x0039), TLS_DHE_DSS_WITH_AES_256_CBC_SHA(0x0038), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256(0xC023), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256(0xC027), TLS_RSA_WITH_AES_128_CBC_SHA256(0x003C), TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256(0xC025), TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256(0xC029), TLS_DHE_RSA_WITH_AES_128_CBC_SHA256(0x0067), TLS_DHE_DSS_WITH_AES_128_CBC_SHA256(0x0040), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA(0xC009), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA(0xC013), TLS_RSA_WITH_AES_128_CBC_SHA(0x002F), TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA(0xC004), TLS_ECDH_RSA_WITH_AES_128_CBC_SHA(0xC00E), TLS_DHE_RSA_WITH_AES_128_CBC_SHA(0x0033), TLS_DHE_DSS_WITH_AES_128_CBC_SHA(0x0032), TLS_EMPTY_RENEGOTIATION_INFO_SCSV(0x00FF)]",
"compression methods" : "00",
"extensions" : [
"status_request (5)": {
"certificate status type": ocsp
"OCSP status request": {
"responder_id": <empty>
"request extensions": {
<empty>
}
}
},
"supported_groups (10)": {
"versions": [secp256r1, secp384r1, secp521r1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, secp256k1, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]
},
"ec_point_formats (11)": {
"formats": [uncompressed]
},
"signature_algorithms (13)": {
"signature schemes": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp512r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
},
"signature_algorithms_cert (50)": {
"signature schemes": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp512r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
},
"status_request_v2 (17)": {
"cert status request": {
"certificate status type": ocsp_multi
"OCSP status request": {
"responder_id": <empty>
"request extensions": {
<empty>
}
}
}
},
"extended_master_secret (23)": {
<empty>
},
"supported_versions (43)": {
"versions": [TLSv1.3, TLSv1.2, TLSv1.1, TLSv1]
},
"psk_key_exchange_modes (45)": {
"ke_modes": [psk_dhe_ke]
},
"key_share (51)": {
"client_shares": [
{
"named group": secp256r1
"key_exchange": {
0000: 04 1F 80 50 D9 C6 03 45 7B 59 0F A7 B6 9E AE 39 ...P...E.Y.....9
0010: 37 BE B0 5B 09 D8 91 37 72 5D 2B 8E 01 0A 84 56 7..[...7r]+....V
0020: 99 0D 37 49 8F 92 61 A9 D6 54 E1 3B EE D1 E8 D2 ..7I..a..T.;....
0030: 92 22 F9 17 CE A7 F8 51 47 C9 1E 5C D6 59 0F 4F .".....QG..\.Y.O
0040: 55
}
},
]
}
]
}
)
...
デバッグ出力には、RAW出力オブジェクト(この場合はOutputStream)に送信された実際のデータが表示されます。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.770 EDT|SSLSocketOutputRecord.java:217|WRITE: TLS13 handshake, length = 405 javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.774 EDT|SSLSocketOutputRecord.java:231|Raw write ( 0000: 16 03 03 01 95 01 00 01 91 03 03 64 CF 68 A1 CF ...........d.h.. 0010: AB B1 6F 43 F6 DE 1B 49 49 DE 5A 42 9A 71 DD CB ..oC...II.ZB.q.. 0020: 9A E3 9F 32 00 E8 87 7A 00 DA C6 20 02 0D BE 1B ...2...z... .... ...
次に、デバッグ出力には、処理が実行される前に入力デバイス(InputStream)から読み取られたRAWデータが表示されます。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.862 EDT|SSLSocketInputRecord.java:215|READ: TLSv1.2 handshake, length = 155 javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.863 EDT|SSLSocketInputRecord.java:474|Raw read ( 0000: 02 00 00 97 03 03 66 24 0F F6 6D 4A 0C 5A A1 23 ......f$..mJ.Z.# 0010: F6 5D 4B 87 B1 6E AC 13 BB 4D C1 A4 0F F0 2C EF .]K..n...M....,. 0020: D7 4F 03 11 19 B1 20 02 0D BE 1B A4 5F F2 E8 B6 .O.... ....._... ...
クライアントがメッセージの送信または読取りを行うときは必ず、送信または読み取られたrawデータと、メッセージ(およびその拡張)の処理内容がデバッグ出力に表示されます。 次の各項では、その部分のデバッグ出力は省略されています。
この時点で、TLS 1.3はネゴシエーション済です。 サーバーがTLSバージョンを選択し、サーバー・バージョンとsupported_versions拡張の組合せを使用して応答します。 この場合、TLSv1.3プロトコルが指定されました。
ServerHelloメッセージでは、次の項目を指定します。
サーバー・バージョン: TLS 1.3の場合、この値はTLSv1.2であることが必要です。TLS 1.3では、このフィールドではなく、supported_versions拡張を使用して、ネゴシエートするプロトコル・バージョンを指定します
ランダム: 暗号化アルゴリズムの初期化にも使用されます
セッションID: TLS 1.3では、ClientHelloメッセージの対応するフィールドと同じ値になります
暗号化方式群: 選択した暗号化方式群(この例では、TLS_AES_128_GCM_SHA256)
圧縮方法: TLS 1.3の場合は、値0が指定されている必要があります
拡張機能
supported_versions: サーバーで使用するTLSバージョンを指定します。 TLS 1.3では、サーバーはクライアント・バージョン・フィールドの値ではなく、ClientHelloメッセージのsupported_versions拡張の値を使用して、バージョンのネゴシエーションを行う必要があります。
key_share: ECDHEキー交換用の名前付きグループとキーの値
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.863 EDT|SSLSocketInputRecord.java:251|READ: TLSv1.2 handshake, length = 155
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.867 EDT|ServerHello.java:862|Consuming ServerHello handshake message (
"ServerHello": {
"server version" : "TLSv1.2",
"random" : "66 24 0F F6 6D 4A 0C 5A A1 23 F6 5D 4B 87 B1 6E AC 13 BB 4D C1 A4 0F F0 2C EF D7 4F 03 11 19 B1",
"session id" : "02 0D BE 1B A4 5F F2 E8 B6 31 9D A4 EF F3 22 84 C3 58 0B 5C C0 57 0F A5 6D 8A 83 EB DC DA B1 B6",
"cipher suite" : "TLS_AES_128_GCM_SHA256(0x1301)",
"compression methods" : "00",
"extensions" : [
"supported_versions (43)": {
"selected version": [TLSv1.3]
},
"key_share (51)": {
"server_share": {
"named group": secp256r1
"key_exchange": {
0000: 04 DE 5B 20 0E FD EB 6E DA 70 C2 D0 FA 0D 4C 53 ..[ ...n.p....LS
0010: 6D E1 9E 67 77 65 36 AF B5 EB E6 D2 88 92 9B EE m..gwe6.........
0020: E4 97 A3 B3 C1 FB D8 29 3B 92 87 D2 B3 9E 3D AA .......);.....=.
0030: 14 99 1E 84 8F C2 E9 E3 E1 AC 9A 12 95 F0 26 B5 ..............&.
0040: 88
}
},
}
]
}
)
...
セッションが初期化されます。
javax.net.ssl|ALL|01|main|2018-08-18 01:04:47.873 EDT|SSLSessionImpl.java:203|Session initialized: Session(1534568687873|TLS_AES_128_GCM_SHA256) ...
ハンドシェークのこの時点で、十分な暗号化情報が交換されているので、ハンドシェークの残りの部分は暗号化して実行されます。
EncryptedExtensionsメッセージには、個々の証明書に固有のものを除いて、暗号化パラメータの決定に必要とされないClientHello拡張に対する応答が含まれます。この例では、クライアントがキー交換でサポートしている名前付きグループのリストが返されます。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.942 EDT|EncryptedExtensions.java:171|Consuming EncryptedExtensions handshake message (
"EncryptedExtensions": [
"supported_groups (10)": {
"versions": [secp256r1, secp384r1, secp521r1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, secp256k1, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]
}
]
)
...
証明書ベースのクライアント認証が必要な場合、サーバーはCertificateRequestメッセージを送信します。 このメッセージには、その証明書に必要なパラメータが含まれています。 次のことを指定します。
certificate_request_context: 証明書要求を識別する文字列。このフィールドの値は長さゼロです(ポストハンドシェーク認証で使用される場合を除く)
拡張: 次の2つの拡張では、デジタル署名で使用できる署名アルゴリズムを指定します。
signature_algorithms: TLS 1.2で最初に導入されたもので、CertificateVerifyメッセージの署名に適用されます
signature_algorithms_cert: 証明書の署名に適用されます
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.947 EDT|CertificateRequest.java:864|Consuming CertificateRequest handshake message (
"CertificateRequest": {
"certificate_request_context": "",
"extensions": [
"signature_algorithms (13)": {
"signature schemes": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp512r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
},
"signature_algorithms_cert (50)": {
"signature schemes": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp512r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
}
]
}
)
...
Certificateメッセージには、認証証明書と、証明書チェーン内のサポートされているその他の証明書が含まれています。 次のことを指定します。
TrustManagerが実際に呼び出されて受信した証明書を検証するときに信頼されます。 信頼の確立には様々な方法があるため、デフォルトのX509TrustManagerで必要な信頼管理のタイプが実行されていない場合は、独自のX509TrustManagerをSSLContextに指定できます。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:47.964 EDT|CertificateMessage.java:1148|Consuming server Certificate handshake message (
"Certificate": {
"certificate_request_context": "",
"certificate_list": [
{
"certificate" : {
"version" : "v1",
"serial number" : "41 00 44 46",
"signature algorithm": "MD5withRSA",
"issuer" : "CN=localhost, OU=Widget Development Group, O="Ficticious Widgets, Inc.", L=Sunnyvale, ST=CA, C=US",
"not before" : "2004-07-22 18:48:38.000 EDT",
"not after" : "2011-05-22 18:48:38.000 EDT",
"subject" : "CN=localhost, OU=Widget Development Group, O="Ficticious Widgets, Inc.", L=Sunnyvale, ST=CA, C=US",
"subject public key" : "RSA"}
"extensions": {
<no extension>
}
},
]
}
)
...
クライアントは、この証明書を認識し、信頼することができます。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.165 EDT|X509TrustManagerImpl.java:242|Found trusted certificate (
"certificate" : {
"version" : "v1",
"serial number" : "41 00 44 46",
"signature algorithm": "MD5withRSA",
"issuer" : "CN=localhost, OU=Widget Development Group, O="Ficticious Widgets, Inc.", L=Sunnyvale, ST=CA, C=US",
"not before" : "2004-07-22 18:48:38.000 EDT",
"not after" : "2011-05-22 18:48:38.000 EDT",
"subject" : "CN=localhost, OU=Widget Development Group, O="Ficticious Widgets, Inc.", L=Sunnyvale, ST=CA, C=US",
"subject public key" : "RSA"}
)
...
サーバーから送信された証明書は、CertificateVerifyメッセージで検証します。 このメッセージを使用して、サーバーがその証明書に対応する秘密キーを持っていることを明示的に証明します。 このメッセージでは、次の項目を指定します。
署名アルゴリズム: 使用された署名アルゴリズム(この例では、rsa_pss_rsae_sha256)。
署名: Certificateメッセージ内の公開キーに対応する秘密キーを使用したハンドシェーク全体に対する署名
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.194 EDT|CertificateVerify.java:1128|Consuming CertificateVerify handshake message (
"CertificateVerify": {
"signature algorithm": rsa_pss_rsae_sha256
"signature": {
0000: 0F 25 DD 62 03 6B 8C 8F 22 C7 8D 46 A2 A6 45 39 .%.b.k.."..F..E9
0010: 08 8D 51 1E 48 52 66 A4 F8 28 D3 FD 18 93 70 C6 ..Q.HRf..(....p.
0020: 32 74 C1 CC 0A C4 60 41 50 AF 7C DA 0C DB 92 F9 2t....`AP.......
0030: 14 CB EF 15 7F 3E 52 16 F7 CC 8A 7C C9 1F 42 CA .....>R.......B.
0040: 90 8D FA B7 F2 3A 46 7E F7 9F 43 CE C6 AA 15 59 .....:F...C....Y
0050: EE AD 34 10 FF B7 BC FD A2 F7 F3 1A FA 7F 26 61 ..4...........&a
0060: 80 2B 50 3A 8A 9E 5C 0E 4C A6 24 DA E6 3D 71 FA .+P:..\.L.$..=q.
0070: AE 78 79 D2 DA 36 DE C1 A6 BC 18 46 04 CE 03 4E .xy..6.....F...N
}
}
)
...
サーバーがFinishedメッセージを送信します。 このメッセージには、ハンドシェーク全体に対するMessage Authentication Code (MAC)が含まれています。
javax.net.ssl|DEBUG|01|main|2018-08-17 01:56:26.764 EDT|Finished.java:860|Consuming server Finished handshake message (
"Finished": {
"verify data": {
0000: CA 7B 74 A6 79 36 ED 62 A7 0E 14 9D 9F D0 4A 0F ..t.y6.b......J.
0010: 02 4C 78 BB E2 89 A2 C6 E8 BD 28 CA E7 D9 DB 68 .Lx.......(....h
}'}
)
...
サーバーがCertificateRequestメッセージでクライアント認証を要求したので、クライアントはCertificateメッセージを送信します。 このCertificateメッセージには、サーバーのCertificateメッセージと同様の情報が指定されます。 クライアントは資格証明をサーバーに送信して戻す必要があるため、そのX509KeyManagerが参照されます。 クライアントは、受け入れられる発行者のリストと、KeyStoreに保管された証明書が一致することを期待します。 この場合は一致しました。クライアントは「duke」としてクレデンシャルを有することになります。 これらの資格証明を受け入れるかどうかを判断するのは、サーバーのX509TrustManagerです。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.222 EDT|CertificateMessage.java:1116|Produced client Certificate message (
"Certificate": {
"certificate_request_context": "",
"certificate_list": [
{
"certificate" : {
"version" : "v1",
"serial number" : "3B 0A FA 66",
"signature algorithm": "MD5withRSA",
"issuer" : "CN=Duke, OU=Java Software, O="Sun Microsystems, Inc.", L=Cupertino, ST=CA, C=US",
"not before" : "2001-05-22 19:46:46.000 EDT",
"not after" : "2011-05-22 19:46:46.000 EDT",
"subject" : "CN=Duke, OU=Java Software, O="Sun Microsystems, Inc.", L=Cupertino, ST=CA, C=US",
"subject public key" : "RSA"}
"extensions": {
<no extension>
}
},
]
}
)
...
サーバーから送信されたCertificateVerifyメッセージと同様に、クライアントが送信した証明書はCertificateVerifyメッセージで検証します。 このメッセージを使用して、クライアントがその証明書に対応する秘密キーを持っていることを明示的に証明します。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.268 EDT|CertificateVerify.java:1097|Produced client CertificateVerify handshake message (
"CertificateVerify": {
"signature algorithm": rsa_pss_rsae_sha256
"signature": {
0000: 91 C2 F7 5D 8D 90 B4 82 E4 BA C6 23 08 E2 B4 DD ...].......#....
0010: 8D 95 8F 9F 31 4F 26 F3 97 3B FB 5B 10 4D AE F6 ....1O&..;.[.M..
0020: 71 78 FB 7B 3A 4F F6 1B BF D2 E3 FB BE 53 F6 70 qx..:O.......S.p
0030: 7E 73 83 F4 9A 5E 08 19 63 C1 97 4C 10 B1 C7 3F .s...^..c..L...?
0040: 4A 7D EF 4A 30 44 15 9F D0 F2 8B C4 D1 45 69 B1 J..J0D.......Ei.
0050: D9 DB 45 83 C4 11 91 B3 81 5E 69 F4 5C 2A CF 69 ..E......^i.\*.i
0060: D3 A6 7E 75 B4 C9 30 FB 5B AC BA 9F A3 C5 0C FD ...u..0.[.......
0070: 9A 62 A4 DA 5A 80 6B 72 CD F5 A5 53 AD 14 74 1C .b..Z.kr...S..t.
}
}
)
次に、クライアントは自身のFinishedメッセージをサーバーに送信します。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.271 EDT|Finished.java:658|Produced client Finished handshake message (
"Finished": {
"verify data": {
0000: 93 04 B5 23 8F 48 3A CF 4A 85 35 9E 5F E0 1D 4C ...#.H:.J.5._..L
0010: 9C 65 06 D4 E8 B4 ED 8F 01 6B 1E A2 DD 18 BD 78 .e.......k.....x
}'}
)
...
クライアントとサーバーによって、それぞれのピアから受信したFinishedメッセージが検証されました。 これで、両方の側は接続を介してアプリケーション・データを送受信できるようになりました。
サーバーとクライアントでアプリケーション・データを交換する準備が整いました。 クライアントがGET /index.html HTTP1.0コマンドを送信します。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.375 EDT|SSLCipher.java:2019|Plaintext before ENCRYPTION ( 0000: 47 45 54 20 2F 69 6E 64 65 78 2E 68 74 6D 6C 20 GET /index.html 0010: 48 54 54 50 2F 31 2E 30 0D 0A 0D 0A 17 00 00 00 HTTP/1.0........ 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 ............. ) ...
通信データは暗号化されます。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.385 EDT|SSLSocketOutputRecord.java:295|Raw write ( 0000: 17 03 03 00 3D 90 BF D1 81 E6 A3 E7 DA 50 A9 8B ....=........P.. 0010: 18 F5 4B 30 AE 59 41 81 25 C4 9E 3E 70 29 5D C6 ..K0.YA.%..>p)]. 0020: 64 49 0B 4A 0E 93 E3 8F DC 42 BA B5 21 42 38 88 dI.J.....B..!B8. 0030: 62 4D 0C 86 FE 9A 8C B9 95 EF 89 93 61 3C 13 69 bM..........a<.i 0040: 6C 45 lE ) ...
クライアントのFinishedメッセージを受信すると、サーバーはクライアントが今後のハンドシェークを高速化するために使用できるPSKチケットが含まれているNewSessionTicketメッセージをいつでも送信できるようになります。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.517 EDT|NewSessionTicket.java:330|Consuming NewSessionTicket message (
"NewSessionTicket": {
"ticket_lifetime" : "86,400",
"ticket_age_add" : "<omitted>",
"ticket_nonce" : "01",
"ticket" : "A5 30 8C B6 AD 95 79 E8 2A D1 95 C0 F0 2F 6F AA 9E 97 58 AA 3D 19 82 2D 2C 47 C0 ED BF 64 48 AB",
"extensions" : [
<no extension>
]
}
)
新しく生成された外部キー情報が添付された状態で、重複したSSLSessionが作成されます。
javax.net.ssl|ALL|01|main|2018-08-18 01:04:48.517 EDT|SSLSessionImpl.java:203|Session initialized: Session(1534568687873|TLS_AES_128_GCM_SHA256)
...
クライアントはサーバーからアプリケーション・データ(最初にHTTPSヘッダー、その後で実際のデータ)を受信します。
javax.net.ssl|ALL|01|main|2018-08-18 01:04:48.517 EDT|SSLSessionImpl.java:203|Session initialized: Session(1534568687873|TLS_AES_128_GCM_SHA256)
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.617 EDT|SSLSocketInputRecord.java:474|Raw read (
0000: 17 03 03 00 63 ....c
)
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.618 EDT|SSLSocketInputRecord.java:215|READ: TLSv1.2 application_data, length = 99
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.618 EDT|SSLSocketInputRecord.java:474|Raw read (
0000: 65 87 0E 1E 78 F7 AC C4 F7 C6 4D 55 91 6F 72 CC e...x.....MU.or.
0010: 18 2D 74 C3 B6 7B 2A F9 EB 2B F4 A8 C7 FD 09 FA .-t...*..+......
0020: 7E 36 9D F7 88 E7 44 DD 60 AF EB B0 F8 CF E1 64 .6....D.`......d
0030: 0D 9B F4 B0 24 C2 BC B1 BF F7 F2 B6 CB E4 2E 39 ....$..........9
0040: 78 B8 73 09 91 65 7A 0F 4C 49 DE 9A 7F 7B 42 86 x.s..ez.LI....B.
0050: CA 33 87 DB 0D B2 E5 61 3C 70 6F F9 6A 15 A9 74 .3.....a<po.j..t
0060: 64 E0 B0 d..
)
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.619 EDT|SSLSocketInputRecord.java:251|READ: TLSv1.2 application_data, length = 99
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.621 EDT|SSLCipher.java:1914|Plaintext after DECRYPTION (
0000: 48 54 54 50 2F 31 2E 30 20 32 30 30 20 4F 4B 0D HTTP/1.0 200 OK.
0010: 0A 43 6F 6E 74 65 6E 74 2D 4C 65 6E 67 74 68 3A .Content-Length:
0020: 20 32 35 37 37 0D 0A 43 6F 6E 74 65 6E 74 2D 54 2577..Content-T
0030: 79 70 65 3A 20 74 65 78 74 2F 68 74 6D 6C 0D 0A ype: text/html..
0040: 0D 0A ..
)
...
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.626 EDT|SSLSocketInputRecord.java:215|READ: TLSv1.2 application_data, length = 2610
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.628 EDT|SSLSocketInputRecord.java:474|Raw read (
0000: 69 8D F9 A3 E9 25 09 87 F0 E0 A1 63 12 9D 81 DF i....%.....c....
0010: 42 FC FA 7A 03 74 FD D5 ED 47 6C 5F 61 F2 BB 39 B..z.t...Gl_a..9
0020: CF 64 0B B2 10 14 24 99 A3 66 8B D2 13 C9 66 FD .d....$..f....f.
...
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.642 EDT|SSLSocketInputRecord.java:251|READ: TLSv1.2 application_data, length = 2610
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.647 EDT|SSLCipher.java:1914|Plaintext after DECRYPTION (
0000: 3C 21 44 4F 43 54 59 50 45 20 68 74 6D 6C 20 50 <!DOCTYPE html P
0010: 55 42 4C 49 43 20 22 2D 2F 2F 57 33 43 2F 2F 44 UBLIC "-//W3C//D
0020: 54 44 20 58 48 54 4D 4C 20 31 2E 30 20 54 72 61 TD XHTML 1.0 Tra
0030: 6E 73 69 74 69 6F 6E 61 6C 2F 2F 45 4E 22 0A 20 nsitional//EN".
...
サーバーは、このセッションではこれ以上メッセージを送信しないことをクライアントに通知するclose_notifyアラートを送信します。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.658 EDT|Alert.java:232|Received alert message (
"Alert": {
"level" : "warning",
"description": "close_notify"
}
)
サーバーがソケット、TLS接続の順に終了します。
javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.661 EDT|SSLSocketImpl.java:1161|close the underlying socket javax.net.ssl|DEBUG|01|main|2018-08-18 01:04:48.661 EDT|SSLSocketImpl.java:921|close the ssl connection (passive) javax.net.ssl|ALL|01|main|2018-08-18 01:04:48.661 EDT|SSLSocketImpl.java:658|Closing input stream javax.net.ssl|ALL|01|main|2018-08-18 01:04:48.661 EDT|SSLSocketImpl.java:728|Closing output stream