HTTPS Server with Expired Certificate

This section provides a tutorial example showing the behavior of HTTPS server and client programs that use an expired server certificate.

If you are running a HTTPS server with a server certificate that is expired, the HTTPS client program will receive the "handshake_failure" error from the server. Here is a test session shows you this behavior.

1. On the server side, I have a server certificate that was expired some years ago.

herong> date 
Tue Feb 20 14:25:35 -03 2024

herong> keytool -list -keystore herong.jks -storepass HerongJKS 

Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry

my_home, Jul 21, 2018, PrivateKeyEntry, 
Certificate fingerprint (SHA-256): 32:B0:55:65:D2:0D:66:55:E0:0C:...

herong> keytool -exportcert -alias my_home -keystore herong.jks 
  -storepass HerongJKS -file my_home.crt 

herong> keytool -printcert -file my_home.crt 
Owner: CN=Herong Yang, OU=My Unit, O=My Home, L=My City, ST=My State, C=US
Issuer: CN=Herong Yang, OU=My Unit, O=My Home, L=My City, ST=My State, C=US
Serial number: 5cb14364

Valid from: Sat Jul 21 11:45:41 ART 2018 until: Fri Oct 19 11:45:41 ART 2018
...

2. Start the HttpsEchoer.java server with the expired certificate. I see no issues.

herong> java HttpsEchoer.java 

Server started:
Server socket class: class sun.security.ssl.SSLServerSocketImpl
   Socket address = 0.0.0.0/0.0.0.0
   Socket port = 8888
   Need client authentication = false
   Want client authentication = false
   Use client mode = false

3. On the client side, run the HttpsClient.java client program with that expired certificate exported and stored in public.jks. I see the "Socket has been closed or broken" exception.

ava -Djavax.net.ssl.trustStore=public.jks HttpsClient.java
The default SSL socket factory class: 
   class sun.security.ssl.SSLSocketFactoryImpl
Socket class: class sun.security.ssl.SSLSocketImpl
   Remote address = localhost/127.0.0.1
   Remote port = 8888
   Local socket address = /127.0.0.1:53947
   Local address = /127.0.0.1
   Local port = 53947
   Need client authentication = false
   Cipher suite = SSL_NULL_WITH_NULL_NULL
   Protocol = NONE
java.net.SocketException: Socket has been closed or broken
...

4. Re-start the server with debug logging turned on:

java -Djavax.net.debug=ssl:record HttpsEchoer.java 
javax.net.ssl|DEBUG|10|main|2024-02-20 15:25:05.755 ART|
  SSLCipher.java:432|jdk.tls.keyLimits:  entry = AES/GCM/NoPadding 
  KeyUpdate 2^37. AES/GCM/NOPADDING:KEYUPDATE = 137438953472

Server started:
Server socket class: class sun.security.ssl.SSLServerSocketImpl
   Socket address = 0.0.0.0/0.0.0.0
   Socket port = 8888
   Need client authentication = false
   Want client authentication = false
   Use client mode = false

5. Re-start the client with debug logging turned on:

java -Djavax.net.ssl.trustStore=public.jks -Djavax.net.debug=ssl:record 
  HttpsClient.java

javax.net.ssl|DEBUG|10|main|2024-02-20 15:22:11.482 ART|
   SSLCipher.java:432|jdk.tls.keyLimits:  
   entry = AES/GCM/NoPadding KeyUpdate 2^37. 
   AES/GCM/NOPADDING:KEYUPDATE = 137438953472
Socket class: class sun.security.ssl.SSLSocketImpl
   ...

javax.net.ssl|DEBUG|10|main|2024-02-20 15:22:11.746 ART|
   Alert.java:232|Received alert message (
"Alert": {
  "level"      : "fatal",
  "description": "handshake_failure"
}
)
javax.net.ssl|ERROR|10|main|2024-02-20 15:22:11.748 ART|
   TransportContext.java:370|Fatal (HANDSHAKE_FAILURE): 
   Received fatal alert: handshake_failure 
  ...

6. Review debug messages on the server side. I see the real reason why the handshake failed: "No available authentication scheme".

Connection #: 1
Socket class: class sun.security.ssl.SSLSocketImpl
   Remote address = /127.0.0.1
   Remote port = 53962
   Local socket address = /127.0.0.1:8888
   Local address = /127.0.0.1
   Local port = 8888
   Need client authentication = false
javax.net.ssl|DEBUG|10|main|2024-02-20 15:25:46.004 ART|
   SSLSocketInputRecord.java:214|READ: TLSv1.2 handshake, length = 435
javax.net.ssl|DEBUG|10|main|2024-02-20 15:25:46.030 ART|
   SSLSocketOutputRecord.java:261|WRITE: TLSv1.3 handshake, length = 122
javax.net.ssl|ALL|10|main|2024-02-20 15:25:46.051 ART|
   X509Authentication.java:289|No X.509 cert selected for EC
javax.net.ssl|ALL|10|main|2024-02-20 15:25:46.051 ART|
   X509Authentication.java:289|No X.509 cert selected for EdDSA
javax.net.ssl|ALL|10|main|2024-02-20 15:25:46.051 ART|
   X509Authentication.java:289|No X.509 cert selected for RSA
javax.net.ssl|ALL|10|main|2024-02-20 15:25:46.052 ART|
   X509Authentication.java:289|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|ERROR|10|main|2024-02-20 15:25:46.055 ART|
   TransportContext.java:370|Fatal (HANDSHAKE_FAILURE): 
   No available authentication scheme (
"throwable" : {
  javax.net.ssl.SSLHandshakeException: No available authentication scheme
   ...

To resolve the issue is easy. All I need to do is to regenerate a new self-signed server certificate in herong.jks and export it as a trusted certificate for client.

Table of Contents

 About This JDK Tutorial Book

 JDK (Java Development Kit)

 Java Date-Time API

 Date, Time and Calendar Classes

 Date and Time Object and String Conversion

 Number Object and Numeric String Conversion

 Locales, Localization Methods and Resource Bundles

 Calling and Importing Classes Defined in Unnamed Packages

 HashSet, Vector, HashMap and Collection Classes

 Character Set Encoding Classes and Methods

 Character Set Encoding Maps

 Encoding Conversion Programs for Encoded Text Files

 Java Logging

 Socket Network Communication

 Datagram Network Communication

 DOM (Document Object Model) - API for XML Files

 SAX (Simple API for XML)

 DTD (Document Type Definition) - XML Validation

 XSD (XML Schema Definition) - XML Validation

 XSL (Extensible Stylesheet Language)

 Message Digest Algorithm Implementations in JDK

 Private key and Public Key Pair Generation

 PKCS#8/X.509 Private/Public Encoding Standards

 Digital Signature Algorithm and Sample Program

 "keytool" Commands and "keystore" Files

 KeyStore and Certificate Classes

 Secret Key Generation and Management

 Cipher - Encryption and Decryption

 The SSL (Secure Socket Layer) Protocol

 SSL Socket Communication Testing Programs

 SSL Client Authentication

HTTPS (Hypertext Transfer Protocol Secure)

 What Is HTTPS?

 HttpsHello.java - HTTPS Server Test Program

 HttpsClient.java - HTTPS Client Test Program

 HttpsClient.java Failed with JDK 1.8

 Using SO_LINGER Socket Option

HTTPS Server with Expired Certificate

 Connecting to HttpsHello.java with IE

 HttpsEchoer.java - A Better HTTPS Server

 Outdated Tutorials

 References

 Full Version in PDF/EPUB