本文主要是介绍使用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握手信息
- 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握手消息
- 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
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消息包括对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_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消息验证。该消息证明服务器拥有它的证书对应的私钥。它是这样定义的:
- 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握手消息
包含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握手消息
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消息
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请求
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连接测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!