使用Firefox浏览器做JDK11 TLS1.3连接测试

2023-11-02 01:40

本文主要是介绍使用Firefox浏览器做JDK11 TLS1.3连接测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

使用Firefox浏览器做JDK11 TLS1.3连接测试

  • 准备
  • Debug Output Format
  • 启动日志
    • 启动
    • Determine Client-Side and Server-Side Enabled Cipher Suites
    • 初始化X509KeyManager
    • 初始化TrustManager
  • 握手和请求流程
    • 服务器收到ClientHello握手信息
    • 产生ServerHello握手消息
    • Change Cipher Spec
    • 产生EncryptedExtensions消息
    • 产生server Certificate消息
    • 产生server CertificateVerify握手消息
    • 产生server Finished握手消息
    • 消费ChangeCipherSpec消息和client Finished握手消息
    • 产生NewSessionTicket消息
    • 收到HTTP请求
    • WRITE: TLS13 application_data
      • 写响应头
      • 写文件

准备

JDK11开始支持TLS1.3了:JEP 332。
理解TLS连接,有时候是困难的,特别是不清楚实际上发送和接收的消息的时候。JSSE有一个内置的调试设施,设置系统属性javax.net.debug可以激活。想知道更多信息,参见Debugging Utilities。
下面看一看TLS 1.3握手时的调试输出。
例子使用默认的JSSE X509KeyManager和X509TrustManager。
ClassFileServer.java:

import java.io.*;
import java.net.*;
import java.security.KeyStore;
import javax.net.*;
import javax.net.ssl.*;
import javax.security.cert.X509Certificate;/* ClassFileServer.java -- 一个简单的文件服务器,* 支持HTTP GET请求,支持secure channel** The ClassFileServer 实现了 a ClassServer,从文件系统读文件。*/public class ClassFileServer extends ClassServer {private String docroot;private static int DefaultServerPort = 2001;/*** 构造ClassFileServer.** @param docroot 定位文件的路径*/public ClassFileServer(ServerSocket ss, String docroot) throws IOException{super(ss);this.docroot = docroot;}/*** 返回的byte[]是文件的内容** @return the bytes for the file* @exception FileNotFoundException,找不到文件时*/public byte[] getBytes(String path)throws IOException{System.out.println("reading: " + path);File f = new File(docroot + File.separator + path);int length = (int)(f.length());if (length == 0) {throw new IOException("File length is zero: " + path);} else {FileInputStream fin = new FileInputStream(f);DataInputStream in = new DataInputStream(fin);byte[] bytecodes = new byte[length];in.readFully(bytecodes);return bytecodes;}}/*** Main方法* 两个命令行参数* port是服务器端口 * docroot是文件路径** <code>   new ClassFileServer(port, docroot);* </code>*/public static void main(String args[]){System.out.println("USAGE: java ClassFileServer port docroot [TLS [true]]");System.out.println("");System.out.println("If the third argument is TLS, it will start as\n" +"a TLS/SSL file server, otherwise, it will be\n" +"an ordinary file server. \n" +"If the fourth argument is true,it will require\n" +"client authentication as well.");int port = DefaultServerPort;String docroot = "";if (args.length >= 1) {port = Integer.parseInt(args[0]);}if (args.length >= 2) {docroot = args[1];}String type = "PlainSocket";if (args.length >= 3) {type = args[2];}try {ServerSocketFactory ssf =ClassFileServer.getServerSocketFactory(type);ServerSocket ss = ssf.createServerSocket(port);if (args.length >= 4 && args[3].equals("true")) {((SSLServerSocket)ss).setNeedClientAuth(true);}new ClassFileServer(ss, docroot);} catch (IOException e) {System.out.println("Unable to start ClassServer: " +e.getMessage());e.printStackTrace();}}private static ServerSocketFactory getServerSocketFactory(String type) {if (type.equals("TLS")) {SSLServerSocketFactory ssf = null;try {// set up key manager to do server authenticationSSLContext ctx;KeyManagerFactory kmf;KeyStore ks;char[] passphrase = "passphrase".toCharArray();ctx = SSLContext.getInstance("TLS");kmf = KeyManagerFactory.getInstance("SunX509");ks = KeyStore.getInstance("JKS");ks.load(new FileInputStream("testkeys"), passphrase);kmf.init(ks, passphrase);ctx.init(kmf.getKeyManagers(), null, null);ssf = ctx.getServerSocketFactory();return ssf;} catch (Exception e) {e.printStackTrace();}} else {return ServerSocketFactory.getDefault();}return null;}
}

ClassServer.java:

import java.io.*;
import java.net.*;
import javax.net.*;/** ClassServer.java -- 一个简单的文件服务器,* 支持HTTP GET请求,支持secure channel*//*** */
public abstract class ClassServer implements Runnable {private ServerSocket server = null;protected ClassServer(ServerSocket ss){server = ss;newListener();}public abstract byte[] getBytes(String path)throws IOException, FileNotFoundException;/*** "listen"线程接受连接,解析头,获得文件名* 发送文件内容*/public void run(){Socket socket;// 接受连接try {socket = server.accept();} catch (IOException e) {System.out.println("Class Server died: " + e.getMessage());e.printStackTrace();return;}// 增加线程,接受下一个连接newListener();try {OutputStream rawOut = socket.getOutputStream();PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(rawOut)));try {// 从header获取文件BufferedReader in =new BufferedReader(new InputStreamReader(socket.getInputStream()));String path = getPath(in);// 读文件内容byte[] bytecodes = getBytes(path);// 响应文件内容(假设 HTTP/1.0 or later)try {out.print("HTTP/1.0 200 OK\r\n");out.print("Content-Length: " + bytecodes.length +"\r\n");out.print("Content-Type: text/html\r\n\r\n");out.flush();rawOut.write(bytecodes);rawOut.flush();} catch (IOException ie) {ie.printStackTrace();return;}} catch (Exception e) {e.printStackTrace();// 错误响应out.println("HTTP/1.0 400 " + e.getMessage() + "\r\n");out.println("Content-Type: text/html\r\n\r\n");out.flush();}} catch (IOException ex) {System.out.println("error writing response: " + ex.getMessage());ex.printStackTrace();} finally {try {socket.close();} catch (IOException e) {}}}/*** 增加新线程*/private void newListener(){(new Thread(this)).start();}/*** 解析HTML header,返回文件路径*/private static String getPath(BufferedReader in)throws IOException{String line = in.readLine();String path = "";if (line.startsWith("GET /")) {line = line.substring(5, line.length()-1).trim();int index = line.indexOf(' ');if (index != -1) {path = line.substring(0, index);}}// 剩余的headerdo {line = in.readLine();} while ((line.length() != 0) &&(line.charAt(0) != '\r') && (line.charAt(0) != '\n'));if (path.length() != 0) {return path;} else {throw new IOException("Malformed Header");}}
}

Debug Output Format

每行调试输出,包括下列信息,以“|”分隔:

  • Logger name (System.getLogger(“javax.net.ssl”))
  • Debug level (System.Logger.Level)
  • Thread ID (Thread.currentThread().getId())
  • Thread name (Thread.currentThread().getName())
  • Date and time
  • Caller (location of the logging call)
  • Message

启动日志

启动

调试程序。
程序参数是:8900 . TLS。
虚拟机选项是-Djavax.net.debug=all。
在当前路径下,要包括testkeys文件。

修改浏览器参数,使浏览器支持TLS1.3,对于Firefox,设置security.tls.version.max等于4。

Determine Client-Side and Server-Side Enabled Cipher Suites

检查系统属性jdk.tls.client.cipherSuites和jdk.tls.server.cipherSuites,决定默认打开的cipher suites。

javax.net.ssl|DEBUG|01|main|2018-10-29 14:00:52.396 CST|SSLContextImpl.java:427|System property jdk.tls.client.cipherSuites is set to 'null'
javax.net.ssl|DEBUG|01|main|2018-10-29 14:00:52.415 CST|SSLContextImpl.java:427|System property jdk.tls.server.cipherSuites is set to 'null'

默认的cipher suites是SunJSSE。
检查jdk.tls.keyLimits决定算法可以使用密钥加密的数据量。

javax.net.ssl|DEBUG|01|main|2018-10-29 14:00:52.459 CST|SSLCipher.java:437|jdk.tls.keyLimits:  entry = AES/GCM/NoPadding KeyUpdate 2^37. AES/GCM/NOPADDING:KEYUPDATE = 137438953472

然后是不支持的或者关闭的cipher suites:

javax.net.ssl|DEBUG|01|main|2018-10-29 14:00:52.482 CST|SSLContextImpl.java:401|Ignore disabled cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
javax.net.ssl|ALL|01|main|2018-10-29 14:00:52.482 CST|SSLContextImpl.java:410|Ignore unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
javax.net.ssl|DEBUG|01|main|2018-10-29 14:00:52.483 CST|SSLContextImpl.java:401|Ignore disabled cipher suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
......

初始化X509KeyManager

X509KeyManager被初始化。
提供的KeyStore有一个给localhost的keyEntry。

javax.net.ssl|DEBUG|01|main|2018-10-29 14:00:52.543 CST|SunX509KeyManagerImpl.java:164|found key for : localhost ("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-23 06:48:38.000 CST","not  after"         : "2011-05-23 06:48:38.000 CST","subject"            : "CN=localhost, OU=Widget Development Group, O="Ficticious Widgets, Inc.", L=Sunnyvale, ST=CA, C=US","subject public key" : "RSA"}
)

初始化TrustManager

初始化TrustManager,发现truststore内有CA证书。也有自签名的证书“localhost”。

javax.net.ssl|DEBUG|01|main|2018-10-29 14:00:52.546 CST|TrustStoreManager.java:112|trustStore is: /home/leishu/soft/jdk-11/lib/security/cacerts
trustStore type is: pkcs12
trustStore provider is: 
the last modified time is: Thu Aug 23 09:54:36 CST 2018
javax.net.ssl|DEBUG|01|main|2018-10-29 14:00:52.546 CST|TrustStoreManager.java:311|Reload the trust store
javax.net.ssl|DEBUG|01|main|2018-10-29 14:00:52.600 CST|TrustStoreManager.java:318|Reload trust certs
javax.net.ssl|DEBUG|01|main|2018-10-29 14:00:52.601 CST|TrustStoreManager.java:323|Reloaded 92 trust certs
javax.net.ssl|DEBUG|01|main|2018-10-29 14:00:52.686 CST|X509TrustManagerImpl.java:79|adding as trusted certificates ("certificate" : {"version"            : "v3","serial number"      : "00 A6 8B 79 29 00 00 00 00 50 D0 91 F9","signature algorithm": "SHA384withECDSA","issuer"             : "CN=Entrust Root Certification Authority - EC1, OU="(c) 2012 Entrust, Inc. - for authorized use only", OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US","not before"         : "2012-12-18 23:25:36.000 CST","not  after"         : "2037-12-18 23:55:36.000 CST","subject"            : "CN=Entrust Root Certification Authority - EC1, OU="(c) 2012 Entrust, Inc. - for authorized use only", OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US","subject public key" : "EC","extensions"         : [{ObjectId: 2.5.29.19 Criticality=trueBasicConstraints:[CA:truePathLen:2147483647]},{ObjectId: 2.5.29.15 Criticality=trueKeyUsage [Key_CertSignCrl_Sign]},{ObjectId: 2.5.29.14 Criticality=falseSubjectKeyIdentifier [KeyIdentifier [0000: B7 63 E7 1A DD 8D E9 08   A6 55 83 A4 E0 6A 50 41  .c.......U...jPA0010: 65 11 42 49                                        e.BI]]}]},"certificate" : {"version"            : "v3","serial number"      : "0C F0 8E 5C 08 16 A5 AD 42 7F F0 EB 27 18 59 D0","signature algorithm": "SHA1withRSA","issuer"             : "CN=SecureTrust CA, O=SecureTrust Corporation, C=US","not before"         : "2006-11-08 03:31:18.000 CST","not  after"         : "2030-01-01 03:40:55.000 CST","subject"            : "CN=SecureTrust CA, O=SecureTrust Corporation, C=US","subject public key" : "RSA","extensions"         : [{ObjectId: 1.3.6.1.4.1.311.20.2 Criticality=false},{ObjectId: 1.3.6.1.4.1.311.21.1 Criticality=false},{ObjectId: 2.5.29.19 Criticality=trueBasicConstraints:[CA:truePathLen:2147483647]},{ObjectId: 2.5.29.31 Criticality=falseCRLDistributionPoints [[DistributionPoint:[URIName: http://crl.securetrust.com/STCA.crl]]]},{ObjectId: 2.5.29.15 Criticality=falseKeyUsage [DigitalSignatureKey_CertSignCrl_Sign]},{ObjectId: 2.5.29.14 Criticality=falseSubjectKeyIdentifier [KeyIdentifier [0000: 42 32 B6 16 FA 04 FD FE   5D 4B 7A C3 FD F7 4C 40  B2......]Kz...L@0010: 1D 5A 43 AF                                        .ZC.]]}]},......

握手和请求流程

服务器收到ClientHello握手信息

ClientHello

  • Client version:对于TLS 1.3,有一个固定值TLSv1.2。TLS 1.3使用扩展supported_versions,而不是此字段,来协商协议版本
  • Random:用来初始化加密算法的随机数
  • Session ID:旧版本的TLS,使用该ID支持session的恢复(resumption)
  • Cipher Suites:客户端请求的密文族,一些只能用于TLSv1.3
  • Compression methods:对于TLS 1.3,必须是0
  • Extensions
    • status_request:客户端请求OCSP
    • supported_groups:客户端支持的key交换组
    • ec_point_formats:客户端支持的椭圆曲线点名称,uncompressed、compressed或者ansiX962_compressed_prime
    • signature_algorithms:CertificateVerify消息的签名算法
    • signature_algorithms_cert:数字签名的签名算法
    • status_request_v2:TLS 1.3弃用
    • extended_master_secret:在TLS 1.2和之前,该扩展请求双方将握手消息的大部分摘要进主密钥。
    • supported_versions:客户端支持的TLS版本。如果客户端请求TLS 1.3,Client version属性是TLSv1.2,并且该扩展包含TLSv1.3。如果客户端请求TLS 1.2,Client version属性是TLSv1.2,该扩展不存在,或者包含TLSv1.2且没有TLSv1.3。
    • psk_key_exchange_modes:可以被当作preshared keys (PSKs)的key交换模式;此时,客户端和服务器必须提供key_share扩展。
    • key_share:key交换的cryptographic参数。
javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.579 CST|ClientHello.java:788|Consuming ClientHello handshake message (
"ClientHello": {"client version"      : "TLSv1.2","random"              : "01 4D 96 73 D1 2D 9A 02 C2 B4 59 C5 83 E7 22 30 AE CB 10 0F FB 3E 65 F4 C7 EE 8E 45 5E 88 E0 AF","session id"          : "5B A8 3E B1 82 AF 49 4B 0D C1 1A DF 62 49 6B 9B 49 14 24 33 2E 6C D1 C5 8C 7A 08 4D AB 33 13 C2","cipher suites"       : "[TLS_AES_128_GCM_SHA256(0x1301), TLS_CHACHA20_POLY1305_SHA256(0x1303), TLS_AES_256_GCM_SHA384(0x1302), TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256(0xC02B), TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(0xC02F), UNKNOWN-CIPHER-SUITE(0xCCA9)(0xCCA9), UNKNOWN-CIPHER-SUITE(0xCCA8)(0xCCA8), TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384(0xC02C), TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(0xC030), TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA(0xC00A), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA(0xC009), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA(0xC013), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(0xC014), TLS_DHE_RSA_WITH_AES_128_CBC_SHA(0x0033), TLS_DHE_RSA_WITH_AES_256_CBC_SHA(0x0039), TLS_RSA_WITH_AES_128_CBC_SHA(0x002F), TLS_RSA_WITH_AES_256_CBC_SHA(0x0035), SSL_RSA_WITH_3DES_EDE_CBC_SHA(0x000A)]","compression methods" : "00","extensions"          : ["server_name (0)": {type=host_name (0), value=localhost},"extended_master_secret (23)": {<empty>},"renegotiation_info (65,281)": {"renegotiated connection": [<no renegotiated connection>]},"supported_groups (10)": {"versions": [x25519, secp256r1, secp384r1, secp521r1, ffdhe2048, ffdhe3072]},"ec_point_formats (11)": {"formats": [uncompressed]},"application_layer_protocol_negotiation (16)": {[h2, http/1.1]},"status_request (5)": {"certificate status type": ocsp"OCSP status request": {"responder_id": <empty>"request extensions": {<empty>}}},"key_share (51)": {"client_shares": [  {"named group": x25519"key_exchange": {0000: C5 2D CC 89 9B AF E6 85   76 66 2C B1 ED F7 21 3F  .-......vf,...!?0010: DA B1 35 6C BF 3C BB 09   37 81 DA B0 3F BB 93 60  ..5l.<..7...?..`}},{"named group": secp256r1"key_exchange": {0000: 04 D1 D9 46 E2 D4 A9 E2   65 43 28 EC 49 7B 98 28  ...F....eC(.I..(0010: 4A FD DD EB 68 48 90 61   3D 9E E0 F0 3E A5 93 28  J...hH.a=...>..(0020: CE 5F A9 6D DF 43 5D B6   93 FA EB 0C E3 A1 AA 2A  ._.m.C]........*0030: 38 75 8E B3 0F 76 E6 6E   85 0C 36 0F 52 9E 75 18  8u...v.n..6.R.u.0040: 7F }},]},"supported_versions (43)": {"versions": [TLSv1.3, TLSv1.2, TLSv1.1, TLSv1]},"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_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, ecdsa_sha1, rsa_pkcs1_sha1]},"psk_key_exchange_modes (45)": {"ke_modes": [psk_dhe_ke]},"pre_shared_key (41)": {"PreSharedKey": {"identities"    : "  {EB 2D 2B 24 85 ED 36 2F 3E A2 66 B5 3D 96 5A FB 77 44 1D 7C F9 84 4E E5 15 EA 0F CE A7 04 1C E1,-171618248}","binders"       : "  {B2 43 B5 4B 66 98 59 EA 8C 45 15 57 B3 DC 55 88 1B D1 98 14 A3 CE 83 A3 D3 EB 22 F5 AA E8 05 2F}",}}]
}
)

产生ServerHello握手消息

ServerHello

  • Server version:对于TLS 1.3,它的值是TLSv1.2。TLS 1.3使用supported_versions扩展,而不是此字段,表示协商好的协议版本
  • Random:用来初始化cryptographic算法
  • Session ID:对于TLS 1.3,等于ClientHello消息对应属性的值
  • Cipher suite:选择好的密文族,本例中是TLS_AES_128_GCM_SHA256
  • Compression methods:对于TLS 1.3,必须是0
  • Extensions
    • supported_versions:服务器使用的TLS版本。对于TLS 1.3,服务器必须使用ClientHello消息的supported_versions扩展的值
    • key_share:ECDHE key交换的名称组和key值
javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.591 CST|ServerHello.java:580|Produced ServerHello handshake message (
"ServerHello": {"server version"      : "TLSv1.2","random"              : "B4 9B 22 63 77 97 50 10 B3 E7 7E EB C1 86 60 B8 71 E0 1C C1 0F 08 5D 69 34 5D E1 ED 0E DF 5A F9","session id"          : "5B A8 3E B1 82 AF 49 4B 0D C1 1A DF 62 49 6B 9B 49 14 24 33 2E 6C D1 C5 8C 7A 08 4D AB 33 13 C2","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 EA 60 33 55 7B 39 44   CD 33 39 3D 4E A0 7D D1  ..`3U.9D.39=N...0010: 27 94 AD B9 52 A7 23 0E   3F E0 16 3B 05 F6 76 37  '...R.#.?..;..v70020: B5 C2 57 7F 07 8B BF 4A   B1 D6 86 F3 1F A7 CB 1D  ..W....J........0030: AA 33 BA 8A 81 5C BA 4B   6B 77 CC 5D 9E 74 7A 19  .3...\.Kkw.].tz.0040: 7C }},}]
}
)

Change Cipher Spec

Change Cipher Spec

javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.601 CST|SSLCipher.java:1824|KeyLimit read side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.602 CST|SSLCipher.java:1978|KeyLimit write side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.603 CST|SSLSocketOutputRecord.java:225|Raw write (0000: 14 03 03 00 01 01                                  ......
)

产生EncryptedExtensions消息

EncryptedExtensions

此时,要交换足够的加密信息,握手的剩余部分都是加密执行的。
EncryptedExtensions消息包括对ClientHello扩展的响应,这些扩展不是确定加密参数所必须的,也不是特定于单个证书的加密参数。
此例中,是客户端支持的key交换的名称组

javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.605 CST|EncryptedExtensions.java:137|Produced EncryptedExtensions message (
"EncryptedExtensions": ["supported_groups (10)": {"versions": [secp256r1, secp384r1, secp521r1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, secp256k1, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]}
]
)

产生server Certificate消息

Certificate

证书消息包括认证证书和认证链中支持的其他证书。它的定义是:

  • certificate_request_context:对于服务器认证,本属性是空的
  • certificate_list:包含客户端通告的签名算法所签名的证书链。本例中,接收自签名的证书(subject和issue相同)。在初始化期间,就发现过相同的自签名证书,当调用TrustManager验证收到的证书时,会信任它。

有很多不同的方法建立信任,所以,如果默认的X509TrustManager不是你需要的信任管理的类型,你可以给SSL上下文提供自己的X509TrustManager。

javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.617 CST|CertificateMessage.java:998|Produced server Certificate 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-23 06:48:38.000 CST","not  after"         : "2011-05-23 06:48:38.000 CST","subject"            : "CN=localhost, OU=Widget Development Group, O="Ficticious Widgets, Inc.", L=Sunnyvale, ST=CA, C=US","subject public key" : "RSA"}"extensions": {<no extension>}},
]
}
)

产生server CertificateVerify握手消息

CertificateVerify

服务器发送的证书由CertificateVerify消息验证。该消息证明服务器拥有它的证书对应的私钥。它是这样定义的:

  • Signature algorithm:签名算法
  • Signature:证书消息里,握手过程中的签名使用的私钥所对应的公钥
javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.640 CST|CertificateVerify.java:1080|Produced server CertificateVerify handshake message (
"CertificateVerify": {"signature algorithm": rsa_pss_rsae_sha256"signature": {0000: 87 FB 89 92 B5 40 26 C3   17 CA 21 CA D7 5F 44 E4  .....@&...!.._D.0010: C0 04 AC 93 1A 97 B1 B8   B1 97 3B A3 0A 74 F1 8B  ..........;..t..0020: AB 8E B8 6F 9B 9A 02 CB   11 90 41 AF 87 6F 80 F9  ...o......A..o..0030: BD 71 38 40 F3 85 D2 3D   AD FD E4 25 DB C0 E3 07  .q8@...=...%....0040: 46 54 EC 22 32 4A 38 71   3A 79 E8 F0 47 29 EF 31  FT."2J8q:y..G).10050: C6 EB BC E7 34 70 97 0C   7E 15 F3 96 B2 1F 8D 5F  ....4p........._0060: A8 73 46 CE 89 A2 C2 E7   8E 8C 67 0E 58 C9 19 38  .sF.......g.X..80070: 99 71 5B FF 4E A0 2F 7D   55 73 F5 AE B3 5E 2C E3  .q[.N./.Us...^,.}
}
)

产生server Finished握手消息

server Finished

包含Message Authentication Code (MAC) 。

javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.644 CST|Finished.java:745|Produced server Finished handshake message (
"Finished": {"verify data": {0000: 9E 31 2D 60 CA 24 62 13   D3 9F 94 20 E6 C7 47 8A  .1-`.$b.... ..G.0010: 05 75 4A 41 D8 E5 7C C9   1F 09 FF EC 84 97 59 BE  .uJA..........Y.}'}
)

消费ChangeCipherSpec消息和client Finished握手消息

ChangeCipherSpec和client Finished

javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.648 CST|SSLSocketInputRecord.java:213|READ: TLSv1.2 change_cipher_spec, length = 1
javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.648 CST|SSLSocketInputRecord.java:458|Raw read (0000: 01                                                 .
)
javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.648 CST|SSLSocketInputRecord.java:249|READ: TLSv1.2 change_cipher_spec, length = 1
javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.649 CST|ChangeCipherSpec.java:232|Consuming ChangeCipherSpec message

客户端发送的完成消息

javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.649 CST|SSLSocketInputRecord.java:458|Raw read (0000: 17 03 03 00 35                                     ....5
)
javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.649 CST|SSLSocketInputRecord.java:213|READ: TLSv1.2 application_data, length = 53
......
javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.652 CST|Finished.java:978|Consuming client Finished handshake message (
"Finished": {"verify data": {0000: 90 84 A9 0D FD C8 53 FA   BB 47 ED FC FB A8 72 72  ......S..G....rr0010: E5 1C B9 BE A3 F8 B6 34   BC 8E 9F C9 36 37 30 C3  .......4....670.}'}
)

产生NewSessionTicket消息

new session

javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.654 CST|NewSessionTicket.java:256|Produced NewSessionTicket handshake message (
"NewSessionTicket": {"ticket_lifetime"      : "86,400","ticket_age_add"       : "<omitted>","ticket_nonce"         : "01","ticket"               : "2C 61 83 79 B2 26 C1 17 F3 9D 26 1F 11 5E C2 6B D6 BC EB 54 9F B6 2F 52 24 E6 1D AE 16 C0 C7 9A","extensions"           : [<no extension>]
}
)
javax.net.ssl|ALL|0F|Thread-0|2018-10-29 14:00:56.655 CST|SSLSessionImpl.java:203|Session initialized:  Session(1540792856584|TLS_AES_128_GCM_SHA256)

收到HTTP请求

HTTP请求

javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.658 CST|SSLCipher.java:1915|Plaintext after DECRYPTION (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 31   0D 0A 48 6F 73 74 3A 20  HTTP/1.1..Host: 0020: 6C 6F 63 61 6C 68 6F 73   74 3A 38 39 30 30 0D 0A  localhost:8900..0030: 55 73 65 72 2D 41 67 65   6E 74 3A 20 4D 6F 7A 69  User-Agent: Mozi0040: 6C 6C 61 2F 35 2E 30 20   28 58 31 31 3B 20 55 62  lla/5.0 (X11; Ub0050: 75 6E 74 75 3B 20 4C 69   6E 75 78 20 78 38 36 5F  untu; Linux x86_0060: 36 34 3B 20 72 76 3A 36   33 2E 30 29 20 47 65 63  64; rv:63.0) Gec0070: 6B 6F 2F 32 30 31 30 30   31 30 31 20 46 69 72 65  ko/20100101 Fire0080: 66 6F 78 2F 36 33 2E 30   0D 0A 41 63 63 65 70 74  fox/63.0..Accept0090: 3A 20 74 65 78 74 2F 68   74 6D 6C 2C 61 70 70 6C  : text/html,appl00A0: 69 63 61 74 69 6F 6E 2F   78 68 74 6D 6C 2B 78 6D  ication/xhtml+xm00B0: 6C 2C 61 70 70 6C 69 63   61 74 69 6F 6E 2F 78 6D  l,application/xm00C0: 6C 3B 71 3D 30 2E 39 2C   2A 2F 2A 3B 71 3D 30 2E  l;q=0.9,*/*;q=0.00D0: 38 0D 0A 41 63 63 65 70   74 2D 4C 61 6E 67 75 61  8..Accept-Langua00E0: 67 65 3A 20 65 6E 2D 55   53 2C 65 6E 3B 71 3D 30  ge: en-US,en;q=000F0: 2E 35 0D 0A 41 63 63 65   70 74 2D 45 6E 63 6F 64  .5..Accept-Encod0100: 69 6E 67 3A 20 67 7A 69   70 2C 20 64 65 66 6C 61  ing: gzip, defla0110: 74 65 2C 20 62 72 0D 0A   43 6F 6E 6E 65 63 74 69  te, br..Connecti0120: 6F 6E 3A 20 6B 65 65 70   2D 61 6C 69 76 65 0D 0A  on: keep-alive..0130: 55 70 67 72 61 64 65 2D   49 6E 73 65 63 75 72 65  Upgrade-Insecure0140: 2D 52 65 71 75 65 73 74   73 3A 20 31 0D 0A 43 61  -Requests: 1..Ca0150: 63 68 65 2D 43 6F 6E 74   72 6F 6C 3A 20 6D 61 78  che-Control: max0160: 2D 61 67 65 3D 30 0D 0A   0D 0A                    -age=0....
)

WRITE: TLS13 application_data

写响应头

响应头

javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.705 CST|SSLCipher.java:2020|Plaintext before ENCRYPTION (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-T0030: 79 70 65 3A 20 74 65 78   74 2F 68 74 6D 6C 0D 0A  ype: text/html..0040: 0D 0A 17 00 00 00 00 00   00 00 00 00 00 00 00 00  ................0050: 00 00 00                                           ...
)

写文件

响应:返回文件

javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.706 CST|SSLSocketOutputRecord.java:310|WRITE: TLS13 application_data, length = 2577
javax.net.ssl|DEBUG|0F|Thread-0|2018-10-29 14:00:56.708 CST|SSLCipher.java:2020|Plaintext before ENCRYPTION (0000: 3C 21 44 4F 43 54 59 50   45 20 68 74 6D 6C 20 50  <!DOCTYPE html P0010: 55 42 4C 49 43 20 22 2D   2F 2F 57 33 43 2F 2F 44  UBLIC "-//W3C//D0020: 54 44 20 58 48 54 4D 4C   20 31 2E 30 20 54 72 61  TD XHTML 1.0 Tra0030: 6E 73 69 74 69 6F 6E 61   6C 2F 2F 45 4E 22 0A 20  nsitional//EN". 0040: 20 20 20 22 68 74 74 70   3A 2F 2F 77 77 77 2E 77     "http://www.w0050: 33 2E 6F 72 67 2F 54 52   2F 78 68 74 6D 6C 31 2F  3.org/TR/xhtml1/0060: 44 54 44 2F 78 68 74 6D   6C 31 2D 74 72 61 6E 73  DTD/xhtml1-trans0070: 69 74 69 6F 6E 61 6C 2E   64 74 64 22 3E 0A 3C 68  itional.dtd">.<h......

这篇关于使用Firefox浏览器做JDK11 TLS1.3连接测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/327225

相关文章

C语言中联合体union的使用

本文编辑整理自: http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=179471 一、前言 “联合体”(union)与“结构体”(struct)有一些相似之处。但两者有本质上的不同。在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量

Tolua使用笔记(上)

目录   1.准备工作 2.运行例子 01.HelloWorld:在C#中,创建和销毁Lua虚拟机 和 简单调用。 02.ScriptsFromFile:在C#中,对一个lua文件的执行调用 03.CallLuaFunction:在C#中,对lua函数的操作 04.AccessingLuaVariables:在C#中,对lua变量的操作 05.LuaCoroutine:在Lua中,

Vim使用基础篇

本文内容大部分来自 vimtutor,自带的教程的总结。在终端输入vimtutor 即可进入教程。 先总结一下,然后再分别介绍正常模式,插入模式,和可视模式三种模式下的命令。 目录 看完以后的汇总 1.正常模式(Normal模式) 1.移动光标 2.删除 3.【:】输入符 4.撤销 5.替换 6.重复命令【. ; ,】 7.复制粘贴 8.缩进 2.插入模式 INSERT

【Altium】查找PCB上未连接的网络

【更多软件使用问题请点击亿道电子官方网站】 1、文档目标: PCB设计后期检查中找出没有连接的网络 应用场景:PCB设计后期,需要检查是否所有网络都已连接布线。虽然未连接的网络会有飞线显示,但是由于布线后期整板布线密度较高,虚连,断连的网络用肉眼难以轻易发现。用DRC检查也可以找出未连接的网络,如果PCB中DRC问题较多,查找起来就不是很方便。使用PCB Filter面板来达成目的相比DRC

Java面试题:通过实例说明内连接、左外连接和右外连接的区别

在 SQL 中,连接(JOIN)用于在多个表之间组合行。最常用的连接类型是内连接(INNER JOIN)、左外连接(LEFT OUTER JOIN)和右外连接(RIGHT OUTER JOIN)。它们的主要区别在于它们如何处理表之间的匹配和不匹配行。下面是每种连接的详细说明和示例。 表示例 假设有两个表:Customers 和 Orders。 Customers CustomerIDCus

Lipowerline5.0 雷达电力应用软件下载使用

1.配网数据处理分析 针对配网线路点云数据,优化了分类算法,支持杆塔、导线、交跨线、建筑物、地面点和其他线路的自动分类;一键生成危险点报告和交跨报告;还能生成点云数据采集航线和自主巡检航线。 获取软件安装包联系邮箱:2895356150@qq.com,资源源于网络,本介绍用于学习使用,如有侵权请您联系删除! 2.新增快速版,简洁易上手 支持快速版和专业版切换使用,快速版界面简洁,保留主

如何免费的去使用connectedpapers?

免费使用connectedpapers 1. 打开谷歌浏览器2. 按住ctrl+shift+N,进入无痕模式3. 不需要登录(也就是访客模式)4. 两次用完,关闭无痕模式(继续重复步骤 2 - 4) 1. 打开谷歌浏览器 2. 按住ctrl+shift+N,进入无痕模式 输入网址:https://www.connectedpapers.com/ 3. 不需要登录(也就是

Toolbar+DrawerLayout使用详情结合网络各大神

最近也想搞下toolbar+drawerlayout的使用。结合网络上各大神的杰作,我把大部分的内容效果都完成了遍。现在记录下各个功能效果的实现以及一些细节注意点。 这图弹出两个菜单内容都是仿QQ界面的选项。左边一个是drawerlayout的弹窗。右边是toolbar的popup弹窗。 开始实现步骤详情: 1.创建toolbar布局跟drawerlayout布局 <?xml vers

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用。如果你看不懂,请留言。 完整代码: <!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><ti

C#中,decimal类型使用

在Microsoft SQL Server中numeric类型,在C#中使用的时候,需要用decimal类型与其对应,不能使用int等类型。 SQL:numeric C#:decimal