Skip to content

add allowSha1Certificates option to work around JDK 21.0.10 TLS regression#103

Merged
jaredstehler merged 2 commits intomasterfrom
js-allow-sha1-certificates
Mar 12, 2026
Merged

add allowSha1Certificates option to work around JDK 21.0.10 TLS regression#103
jaredstehler merged 2 commits intomasterfrom
js-allow-sha1-certificates

Conversation

@jaredstehler
Copy link
Copy Markdown
Contributor

@jaredstehler jaredstehler commented Mar 6, 2026

JDK 21.0.10 added SHA1 jdkCA & usage TLSServer to jdk.certpath.disabledAlgorithms, causing TLS handshake failures against IMAP servers that present SHA-1 signed certificates chaining to a JDK-bundled CA. This
is a breaking change for callers connecting to legacy mailbox servers.

Rather than globally modifying JVM security properties (which would affect all SSL connections in the process), this adds an opt-in allowSha1Certificates() flag on ImapClientConfiguration.

When set, a custom X509ExtendedTrustManager bypasses CertPathValidator (which enforces the disabled algorithm policy) and instead validates the chain manually via cert.verify(), which the JDK still supports for
SHA-1 at the crypto layer. Standard trust validation still applies: certs must chain to a trusted CA, must not be expired, and signatures must be cryptographically valid — only the algorithm-strength policy
check is relaxed.

Also adds sslCipherSuites() to ImapClientConfiguration to allow re-enabling static-RSA key exchange cipher suites, which JDK 21.0.10 also disabled by default (breaking connections to servers that don't support
ECDHE).

Usage:

  // SHA-1 cert workaround
  ImapClientConfiguration config = ImapClientConfiguration.builder()
      .hostAndPort(HostAndPort.fromParts("mail.example.com", 993))
      .allowSha1Certificates(true)
      .build();
  // Static-RSA cipher suite workaround
  ImapClientConfiguration config = ImapClientConfiguration.builder()
      .hostAndPort(HostAndPort.fromParts("mail.example.com", 993))
      .sslCipherSuites(Set.of(
          "TLS_RSA_WITH_AES_128_CBC_SHA",
          "TLS_RSA_WITH_AES_256_CBC_SHA",
          "TLS_RSA_WITH_AES_128_GCM_SHA256",
          "TLS_RSA_WITH_AES_256_GCM_SHA384"))
      .build();

Tests added:

  • itConnectsToRsaOnlyServerWithStaticRsaCipherSuites — verifies sslCipherSuites re-enables static-RSA key exchange against a Python simulation server that only accepts those suites
  • itConnectsToSha1CertServerWithAllowSha1Certificates — spins up a self-contained Java TLS server with a SHA-1 signed cert and verifies the flag enables connection
  • itFailsConnectingToSha1ServerWithoutAllowSha1Certificates — verifies the default configuration correctly rejects the SHA-1 server

jaredstehler and others added 2 commits March 6, 2026 13:13
…ssion

JDK 21.0.10 added SHA1 jdkCA & usage TLSServer to jdk.certpath.disabledAlgorithms,
causing handshake failures against IMAP servers that present SHA-1 signed certificates
chaining to a JDK-bundled CA. This is a breaking change for existing mailbox connections.

Rather than globally modifying JVM security properties (which would affect all connections
in the process), this adds an opt-in allowSha1Certificates() flag on ImapClientConfiguration.
When set, a custom X509ExtendedTrustManager is used that bypasses CertPathValidator (which
enforces the disabled algorithm policy) and instead validates the chain manually via
cert.verify(), which the JDK still supports for SHA-1 at the crypto layer. Standard
trust validation still applies: certs must chain to a trusted CA, must not be expired,
and signatures must be cryptographically valid.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tests to verify the two workarounds for JDK 21.0.10 TLS regressions:
- StaticRsaCipherSuiteIT verifies that sslCipherSuites re-enables static-RSA
  key exchange against a Python simulation server that only accepts those suites
- Two new SHA-1 tests spin up a self-contained Java TLS server with a SHA-1
  signed cert to verify that allowSha1Certificates=true allows connection and
  that the default configuration (no custom truststore) is correctly rejected

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jaredstehler jaredstehler merged commit c00c14e into master Mar 12, 2026
1 check passed
@jaredstehler jaredstehler deleted the js-allow-sha1-certificates branch March 12, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant