bigywater.tech
Java · 265

Java Security Parameters:算法限制如何影响兼容性

jdk.tls.disabledAlgorithms 与 jdk.certpath.disabledAlgorithms 决定了 Java 拒绝哪些协议、套件和证书算法。三个 JDK 版本的默认值有什么不同?放宽或收紧会发生什么?这篇逐项真实运行,包括 JDK 17、21、27 的对比。

TLSv1.1
默认配置下握手失败的协议(覆盖 jdk.tls.disabledAlgorithms 后成功)
31 个
默认启用的 TLS 套件(JDK 17、21、27 相同)
jdkCA & usage TLSServer
默认 SHA1 限制的适用范围——自建 CA 的链不受它限制

三个 JDK 的默认安全参数

实测 · 本机执行输出
  --- JDK 17 ---
  jdk.tls.disabledAlgorithms = SSLv3, TLSv1, TLSv1.1, DTLSv1.0, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, ECDH, TLS_RSA_*, rsa_pkcs1_sha1 usage HandshakeSignature, ecdsa_sha1 usage HandshakeSignature, dsa_sha1 usage HandshakeSignature
  jdk.certpath.disabledAlgorithms = MD2, MD5, SHA1 jdkCA & usage TLSServer, RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224, SHA1 usage SignedJAR & denyAfter 2019-01-01
  jdk.security.legacyAlgorithms = SHA1, RSA keySize < 2048, DSA keySize < 2048
  jdk.jar.disabledAlgorithms = MD2, MD5, RSA keySize < 1024, DSA keySize < 1024, SHA1 denyAfter 2019-01-01
  crypto.policy = unlimited
  jdk.tls.legacyAlgorithms = NULL, anon, RC4, DES, 3DES_EDE_CBC
  JDK 17.0.20.1:支持的协议 [TLSv1.3, TLSv1.2, TLSv1.1, TLSv1, SSLv3, SSLv2Hello];默认启用的协议(客户端)[TLSv1.3, TLSv1.2];支持的套件 31 个,默认启用 31 个
  默认启用的套件里 CBC 套件 16 个,AEAD(GCM/ChaCha20)套件 14 个;含 3DES 的 0 个,含 RC4 的 0 个
  --- JDK 21 ---
  jdk.tls.disabledAlgorithms = SSLv3, TLSv1, TLSv1.1, DTLSv1.0, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, ECDH, TLS_RSA_*, rsa_pkcs1_sha1 usage HandshakeSignature, ecdsa_sha1 usage HandshakeSignature, dsa_sha1 usage HandshakeSignature
  jdk.certpath.disabledAlgorithms = MD2, MD5, SHA1 jdkCA & usage TLSServer, RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224, SHA1 usage SignedJAR & denyAfter 2019-01-01
  jdk.security.legacyAlgorithms = SHA1, RSA keySize < 2048, DSA keySize < 2048, DES, DESede, MD5, RC2, ARCFOUR
  jdk.jar.disabledAlgorithms = MD2, MD5, RSA keySize < 1024, DSA keySize < 1024, SHA1 denyAfter 2019-01-01
  crypto.policy = unlimited
  jdk.tls.legacyAlgorithms = NULL, anon, RC4, DES, 3DES_EDE_CBC
  JDK 21.0.12.1:支持的协议 [TLSv1.3, TLSv1.2, TLSv1.1, TLSv1, SSLv3, SSLv2Hello];默认启用的协议(客户端)[TLSv1.3, TLSv1.2];支持的套件 31 个,默认启用 31 个
  默认启用的套件里 CBC 套件 16 个,AEAD(GCM/ChaCha20)套件 14 个;含 3DES 的 0 个,含 RC4 的 0 个
  --- JDK 27 ---
  jdk.tls.disabledAlgorithms = SSLv3, TLSv1, TLSv1.1, DTLSv1.0, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, ECDH, TLS_RSA_*, rsa_pkcs1_sha1 usage HandshakeSignature, ecdsa_sha1 usage HandshakeSignature, dsa_sha1 usage HandshakeSignature
  jdk.certpath.disabledAlgorithms = MD2, MD5, SHA1 jdkCA & usage TLSServer, RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224, SHA1 usage SignedJAR & denyAfter 2019-01-01
  jdk.security.legacyAlgorithms = SHA1, RSA keySize < 2048, DSA keySize < 2048, DES, DESede, MD5, RC2, ARCFOUR
  jdk.jar.disabledAlgorithms = MD2, MD5, RSA keySize < 1024, DSA keySize < 1024, SHA1 denyAfter 2019-01-01
  crypto.policy = unlimited
  jdk.tls.legacyAlgorithms = NULL, anon, RC4, DES, 3DES_EDE_CBC
  JDK 27:支持的协议 [TLSv1.3, TLSv1.2, TLSv1.1, TLSv1, SSLv3, SSLv2Hello];默认启用的协议(客户端)[TLSv1.3, TLSv1.2];支持的套件 31 个,默认启用 31 个
  默认启用的套件里 CBC 套件 16 个,AEAD(GCM/ChaCha20)套件 14 个;含 3DES 的 0 个,含 RC4 的 0 个

协议与套件的禁用

实测 · 本机执行输出
  TLSv1.3  → 握手成功:TLSv1.3 TLS_AES_256_GCM_SHA384
  TLSv1.2  → 握手成功:TLSv1.2 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  TLSv1.1  → 握手失败:SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
  TLSv1    → 握手失败:SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
  TLSv1.2 + 套件 TLS_RSA_WITH_AES_128_CBC_SHA(RSA 密钥交换,无前向保密)→ 握手失败:SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
  TLSv1.2 + 套件 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA → 握手成功:TLSv1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
  TLSv1.2 + 套件 TLS_RSA_WITH_3DES_EDE_CBC_SHA → 握手失败:SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
  --- 用 -Djava.security.properties 覆盖 jdk.tls.disabledAlgorithms 为:SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, anon, NULL(去掉了 TLSv1、TLSv1.1、3DES_EDE_CBC、TLS_RSA_* 等)---
  TLSv1.3  → 握手成功:TLSv1.3 TLS_AES_256_GCM_SHA384
  TLSv1.2  → 握手成功:TLSv1.2 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  TLSv1.1  → 握手成功:TLSv1.1 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
  TLSv1    → 握手成功:TLSv1 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
  TLSv1.2 + 套件 TLS_RSA_WITH_AES_128_CBC_SHA(RSA 密钥交换,无前向保密)→ 握手成功:TLSv1.2 TLS_RSA_WITH_AES_128_CBC_SHA
  TLSv1.2 + 套件 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA → 握手成功:TLSv1.2 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
  TLSv1.2 + 套件 TLS_RSA_WITH_3DES_EDE_CBC_SHA → 握手失败:SSLHandshakeException: (handshake_failure) Received fatal alert: handshake_failure

证书路径的算法限制

实测 · 本机执行输出
  正常链 [leaf_sha256, ica] 信任 root → 通过
  叶子用 SHA1withRSA 签名 [leaf_sha1, ica] → 通过
  中间证书用 SHA1withRSA 签名 [leaf_viasha1, ica_sha1] → 通过
  512 位 RSA 的叶子 [leaf_rsa512, ica] → 失败:Algorithm constraints check failed on keysize limits: RSA 512 bit key used with certificate: CN=localhost(原因 ALGORITHM_CONSTRAINED)
  1024 位 RSA 的叶子 [leaf_rsa1024, ica] → 通过
  根证书(信任锚)自己的签名算法是 SHA1withRSA 时(root_sha1 作为锚,链 [leaf_underroot_sha1root])→ 通过(信任锚自身的签名算法不被检查)
  --- 用 -Djava.security.properties 收紧:jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1, RSA keySize < 2048 ---
  正常链 [leaf_sha256, ica] 信任 root → 通过
  叶子用 SHA1withRSA 签名 [leaf_sha1, ica] → 失败:Algorithm constraints check failed on disabled algorithm: SHA1 used with certificate: CN=localhost(原因 ALGORITHM_CONSTRAINED)
  中间证书用 SHA1withRSA 签名 [leaf_viasha1, ica_sha1] → 失败:Algorithm constraints check failed on disabled algorithm: SHA1 used with certificate: CN=Sec ICA SHA1(原因 ALGORITHM_CONSTRAINED)
  512 位 RSA 的叶子 [leaf_rsa512, ica] → 失败:Algorithm constraints check failed on keysize limits: RSA 512 bit key used with certificate: CN=localhost(原因 ALGORITHM_CONSTRAINED)
  1024 位 RSA 的叶子 [leaf_rsa1024, ica] → 失败:Algorithm constraints check failed on keysize limits: RSA 1024 bit key used with certificate: CN=localhost(原因 ALGORITHM_CONSTRAINED)
  根证书(信任锚)自己的签名算法是 SHA1withRSA 时(root_sha1 作为锚,链 [leaf_underroot_sha1root])→ 通过(信任锚自身的签名算法不被检查)

分步演示

Java 安全参数
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK(Temurin 17.0.20、Homebrew 21.0.12 与 27,每篇注明实际用的版本);用 javac 编译、java 直接运行,需要第三方库时用 Maven 解析依赖;计时用 System.nanoTime,数字每次运行会有小幅抖动。JDK 17.0.20、21.0.12、27(Homebrew/Temurin 构建);证书由 keytool 在本机生成;覆盖用 -Djava.security.properties
    • 没有验证:通过 $JAVA_HOME/conf/security/java.security 直接修改的效果与风险、jdk.tls.disabledAlgorithms 的 usage 与 denyAfter 语法的全部取值、DTLS、jdk.jar.disabledAlgorithms 对签名 JAR 的影响、FIPS 模式、其它发行版(OpenJDK 厂商构建)在默认值上的差异;放宽这些限制仅用于兼容旧系统,存在安全风险
    京ICP备2026067502号-1京公网安备11010502063487号