jdk.tls.disabledAlgorithms 与 jdk.certpath.disabledAlgorithms 决定了 Java 拒绝哪些协议、套件和证书算法。三个 JDK 版本的默认值有什么不同?放宽或收紧会发生什么?这篇逐项真实运行,包括 JDK 17、21、27 的对比。
--- 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])→ 通过(信任锚自身的签名算法不被检查)