JEP 288:禁用 SHA-1 证书
概述
通过提供一种更灵活的机制来禁用基于 SHA-1 签名的 X.509 证书链,从而提升 JDK 的安全配置。
非目标
该机制的目标并非禁用所有使用 SHA-1 证书的情况。只有由 CertPathValidator
和 CertPathBuilder
API 的 PKIX
实现,以及 TrustManagerFactory
API 的 SunX509
和 PKIX
实现所验证的 X.509 证书链才会受到限制。JDK 中 X.509 证书的其他用途(如解析等)不受影响。CertPathValidator
、CertPathBuilder
和 TrustManagerFactory
的第三方实现则需直接负责执行其自身的限制。
动机
由于存在碰撞攻击的风险,使用基于 SHA-1 的数字签名算法越来越成为一个安全问题。NIST 在SP 800-57 第 1 部分中建议不再使用 SHA-1 对数据应用数字签名。CA/Browser Forum 的公共信任 SSL 证书的基线要求声明,自 2016 年 1 月 1 日起,证书颁发机构不得使用 SHA-1 发行任何从属 CA 或订阅者证书。其他软件供应商(Google、Microsoft、Mozilla、Apple)已经发布了在证书中弃用 SHA-1 的计划。在 JDK 中,X.509 证书链用于 TLS 中服务器和客户端的身份验证,以及验证签名代码的完整性和作者身份。
描述
SHA-1 证书的使用量持续减少,尤其是对于公开信任的 SSL/TLS 服务器而言(截至 2017 年 3 月 3 日,0.0% 的热门 SSL 网站仍在使用 SHA-1)。然而,许多企业使用私有的证书颁发机构 (Certificate Authority),这些机构通常需要更多时间来适应新的算法限制。此外,先前使用 SHA-1 证书签名并加上时间戳的代码在未来一段时间内应该仍然可以正常运行。因此,禁用 所有 SHA-1 证书可能会破坏许多应用程序。基于此,本 JEP 将增强算法约束机制,以允许实施更灵活的 SHA-1 限制策略。
具体而言,对 jdk.certpath.disabledAlgorithms
安全属性的规范进行了以下增强:
-
一个名为
jdkCA
的新约束,当设置该约束时,如果算法用于由预装在 JDK cacerts 密钥库中的信任锚点所锚定的证书链中,则会限制该算法。此条件不适用于由其他证书锚定的证书链,包括那些随后添加到cacerts
密钥库中的证书链。此外,请注意,该限制不适用于信任锚点证书,因为它们是直接信任的。 -
一个名为
denyAfter
的新约束,当设置该约束时,如果算法在指定日期之后被用于某个证书链中,则会限制该算法。该限制不适用于信任锚点证书,因为它们是直接信任的。另外,签名 JAR 中使用的代码签名证书链将按以下方式特别处理:a. 如果证书链用于未带时间戳的签名 JAR 中,则在指定日期之后将受到限制;
b. 如果证书链用于带时间戳的签名 JAR 中,并且时间戳是在指定日期之前生成的,则不会受到限制。如果 JAR 在指定日期之后生成时间戳,则将受到限制。
-
一个名为
usage
的新约束,当设置该约束时,如果算法用于指定用途的证书链中,则会限制该算法。最初支持三种用途:用于 TLS/SSL 服务器证书链的TLSServer
、用于 TLS/SSL 客户端证书链的TLSClient
和用于签名 JAR 的证书链的SignedJAR
。
上述增强功能后的 jdk.certpath.disabledAlgorithms
安全属性的规范如下(有关每个约束的定义,请参阅 java.security
文件):
DisabledAlgorithms:
" DisabledAlgorithm { , DisabledAlgorithm } "
DisabledAlgorithm:
AlgorithmName [Constraint] { '&' Constraint }
AlgorithmName:
(see below)
Constraint:
KeySizeConstraint | CAConstraint | DenyAfterConstraint |
UsageConstraint
KeySizeConstraint:
keySize Operator KeyLength
Operator:
<= | < | == | != | >= | >
KeyLength:
Integer value of the algorithm's key length in bits
CAConstraint:
jdkCA
DenyAfterConstraint:
denyAfter YYYY-MM-DD
UsageConstraint:
usage [TLSServer] [TLSClient] [SignedJAR]
此外,对 jdk.jar.disabledAlgorithms
安全属性的规范进行了以下增强:
-
一个名为
denyAfter
的新约束,当设置该约束时,如果算法在指定日期之后被用于已签名的 JAR 文件中,则会限制该算法的使用,具体如下:a. 如果 JAR 文件未添加时间戳,则在指定日期之后将受到限制(视为未签名)。
b. 如果 JAR 文件已添加时间戳,并且时间戳早于指定日期,则不会受到限制。如果 JAR 文件的时间戳晚于指定日期,则将受到限制。
上述增强功能后的 jdk.jar.disabledAlgorithms
安全属性的规范如下(有关每个约束的定义,请参阅 java.security
文件):
DisabledAlgorithms:
" DisabledAlgorithm { , DisabledAlgorithm } "
DisabledAlgorithm:
AlgorithmName [Constraint] { '&' Constraint }
AlgorithmName:
(see below)
Constraint:
KeySizeConstraint | DenyAfterConstraint
KeySizeConstraint:
keySize Operator KeyLength
DenyAfterConstraint:
denyAfter YYYY-MM-DD
Operator:
<= | < | == | != | >= | >
KeyLength:
Integer value of the algorithm's key length in bits
这里有一些例子:
要禁用链接到预安装在 cacerts
文件中的信任锚的 SHA-1 证书,请将 "SHA1 jdkCA"
添加到 jdk.certpath.disabledAlgorithms
安全属性中:
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
DSA keySize < 1024, EC keySize < 224, SHA1 jdkCA
要禁用用于 TLS 服务器身份验证并链接到预安装在 cacerts
文件中的信任锚的 SHA-1 证书,请将 "SHA1 jdkCA & usage TLSServer"
添加到 jdk.certpath.disabledAlgorithms
安全属性中:
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
DSA keySize < 1024, EC keySize < 224, SHA1 jdkCA & usage TLSServer
要禁用已签名 JAR 中的 SHA-1(时间戳早于 2017 年 1 月 1 日的 JAR 除外),请将 "SHA1 usage SignedJAR & denyAfter 2017-01-01"
添加到 jdk.certpath.disabledAlgorithms
安全属性,并将 "SHA1 denyAfter 2017-01-01"
添加到 jdk.jar.disabledAlgorithms
安全属性中:
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
DSA keySize < 1024, EC keySize < 224, \
SHA1 usage SignedJAR & denyAfter 2017-01-01
jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
DSA keySize < 1024, SHA1 denyAfter 2017-01-01
测试
许多安全库回归测试目前使用 SHA-1 证书。这些证书将会被修改以重新启用 SHA-1,或者,这些证书将被替换为 SHA-2 证书。
风险与假设
描述部分概述了其他限制条件,这些限制条件将有助于降低某些用例的兼容性风险。我们还将通过其他论坛和计划来传达这些变更,以帮助确保用户了解这些变更,并知道如何在新限制生效之前配置和测试他们的应用程序。