JEP 249:TLS 的 OCSP 装订
概括
通过 TLS 证书状态请求扩展(RFC 6066第 8 节)和多证书状态请求扩展 ( RFC 6961 ) 实施 OCSP 装订。
成功指标
对于客户端和服务器模式,该实现必须与至少两个支持 OCSP 装订的第三方 TLS 实现成功地进行互操作。
动机
检查 X.509 证书的吊销状态是基于证书的有效身份验证的关键部分。然而,使用 OCSP 检查证书状态通常涉及对每个正在检查的证书的网络请求。由于存在额外的网络请求,在客户端启用 OCSP 检查 TLS 可能会对性能产生重大影响。
OCSP 装订允许证书的提供者(而不是颁发证书颁发机构 (CA))承担提供 OCSP 响应的资源成本。在 TLS 上下文中,TLS 服务器负责请求 OCSP 响应并将其在 SSL/TLS 握手期间发送给客户端。这还允许服务器缓存 OCSP 响应并将其提供给所有连接到它的客户端。这显着减少了 OCSP 响应器的负载,因为响应可以由服务器而不是每个客户端进行缓存和定期刷新。
目前,可以在客户端启用证书吊销状态检查。然而,这种经典方法面临着几个挑战:
表现
如果客户端直接从 OCSP 响应器获取吊销状态,则对于与特定服务器建立连接的每个客户端,OCSP 响应器必须以特定的证书状态进行响应。对于高流量网站,OCSP 响应程序很可能是性能瓶颈。此外,撤销状态检查涉及多次往返。如果在客户端启用 OCSP 检查,则会对性能产生重大影响。
安全
Adam Langley 在他的一篇博客中讨论了客户端应用程序在使用传统 OCSP 时面临的安全挑战。他描述了大多数浏览器实现的“软失败”行为,这是一种策略,其中未能联系 OCSP 响应程序不会导致吊销检查失败。这允许攻击者通过拦截或阻止来自客户端的 OCSP 请求,或者通过对响应者本身发起拒绝服务攻击,使客户端绕过吊销检查。
OCSP 装订本身并不能完全缓解这一挑战,但它消除了客户端和响应者之间进行 OCSP 检查的需要。服务器仍然必须能够获取自己的 OCSP 响应并将其放置在带内作为 TLS 握手的一部分。
目前,IETF 中的草案形式是“必须装订”证书扩展的提案,该提案要求在 TLS 握手期间附加 OCSP 响应。从本质上讲,这将覆盖客户端可能采用的任何软故障行为。此提议的扩展超出了本 JEP 的范围,但如果此扩展超出了草案范围,那么它可能是将来有用的补充。
最后,Java 客户端可能不像浏览器那样对软故障默认值有同样 的需求。在某些情况下,客户可能更喜欢硬故障方法,或者选择在无法接收 OCSP 响应时通过对话框获取用户反馈。例如,Java 插件和 Java Web Start 的默认软失败方法是在加载签名的小程序时显示警告对话框。
OCSP 请求的潜在隐私损害
在正常的 OCSP 场景中,当客户端发送 OCSP 请求时,它会将服务器(通过服务器证书条目)和自身(至少通过 IP 地址)暴露给 OCSP 响应者,因此可以泄露客户端行为。 OCSP 装订解决了此问题,因为客户端不再向 OCSP 响应程序发出请求。
“强制门户”技术的局限性
“强制门户”技术强制网络上的 HTTP 客户端在正常使用网络之前下载特殊网页,通常用于身份验证目的。在此类环境中,客户端无法检查 SSL/TLS 证书的 OCSP 状态,因为在身份验证成功之前所有网络访问都会被阻止。
概括
使用 CRL 可以部分缓解上述问题,或者通过 OCSP 装订更好地解决。
总之,OCSP 装订可以通过减少 OCSP 响应器的性能瓶颈来帮助提高 TLS 的性能。它还可以防止OCSP请求潜在的隐私损害,并避免“强制门户”技术的限制。
描述
此功能将在提供程序实现中实现SunJSSE
。计划对 API 进行较小的更改,目标是使这些更改尽可能小。该实现将为 OCSP 特定参数选择合理的默认值,并将通过以下系统属性提供这些默认值的配置:
jdk.tls.client.enableStatusRequestExtension
:此属性默认为 true。这将启用status_request
和status_request_v2
扩展,并启用对CertificateStatus
服务器发送的消息的处理。jdk.tls.server.enableStatusRequestExtension
:该属性默认为 false。这使得服务器端支持 OCSP 装订。jdk.tls.stapling.responseTimeout
:此属性控制服务器用于获取 OCSP 响应的最长时间,无论是从缓存还是通过联系 OCSP 响应程序。如果适用,根据所完成的装订类型,已收到的那些响应将在“CertificateStatus”消息中发送。该属性采用以毫秒为单位的整数值,默认值为 5000。jdk.tls.stapling.cacheSize
:此属性控制条目中的最大缓存大小。默认值为 256 个对象。如果缓存已满并且需要缓存新的响应,则最近最少使用的缓存条目将被新的缓存条目替换。此属性的值为零或更少意味着缓存对其可能包含的响应数量没有上限。jdk.tls.stapling.cacheLifetime
:此属性控制缓存响应的最长寿命。该值以秒为单位指定,默认值为 3600(1 小时)。如果响应的 nextUpdate 字段的过期时间早于缓存生命周期,则响应的生命周期可能比使用此属性设置的值短。此属性的值为零或小于零会禁用缓存生存期。如果对象没有 nextUpdate 并且缓存生存期已禁用,则不会缓存响应。jdk.tls.stapling.responderURI
:此属性允许管理员在用于 TLS 的证书没有权限信息访问扩展的情况下设置默认 URI。除非设置了 jdk.tls.stapling.responderOverride 属性,否则它不会覆盖 AIA 扩展值(见下文)。默认情况下不设置此属性。jdk.tls.stapling.responderOverride
:此属性允许通过 jdk.tls.stapling.responderURI 属性提供的 URI 覆盖任何 AIA 扩展值。默认情况下为 false。jdk.tls.stapling.ignoreExtensions``status_request
:此属性禁用转发或TLS 扩展中指定的 OCSP 扩展status_request_v2
。默认情况下为 false。
客户端和服务器端 Java 实现将能够支持status_request
TLS status_request_v2
hello 扩展。 RFC 6066 中描述了该status_request
扩展。支持服务器将包含用于证书的单个 OCSP 响应,用于在新的 TLS 握手消息 ( CertificateStatus
) 中识别服务器。 RFC 6961 中描述了该status_request_v2
扩展。该扩展允许客户端请求服务器在消息中提供单个 OCSP 响应CertificateStatus
(类似于status_request
),或者请求服务器为消息中提供的证书列表中的每个证书获取 OCSP 响应。证书消息(下面称为ocsp_multi
类型)。
客户端
-
OCSP 装订默认启用,可以通过设置系统属性禁用。这可以通过财产来完成
jdk.tls.client.enableStatusRequestExtension
。 -
默认情况下,客户端将在握手消息中断言
status_request
和status_request_v2
扩展ClientHello
。对于status_request_v2
扩展,ocsp
和ocsp_multi
类型都将被断言。 -
创建 hello 扩展需要在 中创建新类
sun.security.ssl
,类似于ServerNameIndicator
、RenegotiationInfoExtension
和其他扩展的实现方式。 -
为了使用新的扩展,该类
ClientHello
将定义额外的方法来添加这些扩展。这些方法将从 调用ClientHandshaker.clientHello()
。 -
HandshakeMessage
需要在类中创建一个新的握手消息类来处理CertificateStatus
消息的编码和解析。 -
公共 API 需要进行更改,以
ExtendedSSLSession
允许调用者获取握手过程中收到的 OCSP 响应。新方法是:public List<byte[]> getStatusResponses();
服务器端
-
服务器端实现默认禁用 OCSP 装订,但可以通过
jdk.tls.server.enableStatusRequestExtension
系统属性启用。禁用 OCSP 装订支持的服务器将忽略status_request
和status_request_v2
扩展名。 -
消息中的服务器端填充
status_request
或status_request_v2
信息ServerHello
将取决于客户端如何断言这些扩展。一般来说, 中的相同请求扩展ClientHello
将在 中返回ServerHello
,但以下情况除外:-
接收
status_request
和status_request_v2
中的扩展的服务器ClientHello
将status_request_v2
在ServerHello
. -
接收带有和类型的
status_request_v2
扩展的服务器将在消息和消息中断言。ClientHello``ocsp``ocsp_multi``status_request_v2``ServerHello``ocsp_multi``CertificateStatus
-
status_request_v2
在选择/的情况下ocsp_multi
,将使用不同的线程来获取每个响应。这将由一个StatusResponseManager
负责处理 OCSP 响应的获取和缓存的管理器进行管理。
-
-
应尽可能缓存 OCSP 响应。未在其
status_request[_v2]
扩展中指定随机数的客户端可能会收到缓存的响应。-
如果当前时间晚于字段,则不应使用缓存的响应
nextUpdate
。 -
没有
nextUpdate
字段的缓存响应可以在缓存中保留预定的生命周期(请参阅下面的可调参数)。 -
使用随机数扩展进行接收的服务器
status_requests
不得在CertificateStatus
消息中返回缓存的响应。
-
-
服务器端装订支持可通过上述系统属性进行调整。
-
它
StatusResponseManager
是作为SSLContext
实例化的一部分创建的。属性 值在SSLContext
施工期间进行采样。这些属性值可以更改,当SSLContext
创建新对象时,StatusResponseManager 将具有这些新值。
装订和 X509ExtendedTrustManager
开发人员在如何处理通过 OCSP 装订提供的响应方面具有一定的灵活性。此 JEP 没有对证书路径检查和吊销检查中涉及的当前方法进行任何更改。这意味着客户端和服务器都可以断言扩展status_request
,通过消息获取 OCSP 响应CertificateStatus
,并允许用户灵活地对吊销信息或缺少吊销信息做出反应。
与以前的 JDK 版本一样,如果PKIXBuilderParameters
调用者未提供任何信息,则将禁用吊销检查。如果调用者创建PKIXBuilderParameters
并使用该setRevocationEnabled
方法启用吊销检查,则将评估装订 OCSP 响应。如果该com.sun.net.ssl.checkRevocation
属性设置为 ,情况也会如此true
。下表显示了几种不同的方法作为示例(假设在客户端和服务器中都启用了 OCSP 装订):
PKIXBuilder参数
checkReplication 属性
PKIX撤销检查器
结果
默认
默认
默认
撤销检查已禁用
默认
真的
默认
启用撤销检查*,设置 SOFT_FAIL
实例化
默认
默认
启用撤销检查*,设置 SOFT_FAIL
实例化
默认
实例化,添加到 PKIXBuilderParameters
启用吊销检查*,硬故障行为。
* 仅当 ocsp.enable Security 属性设置为 true 时,才会发生客户端 OCSP 回退
PKIXBuilderParameters
有关和对象的配置PKIXRevocationChecker
及其与 JSSE 关系的更多详细信息,请参阅_Java PKI API 程序员指南_和_JSSE 参考指南_。
测试
-
OCSP Stapling 实现不得破坏向后兼容性。
-
客户端实现必须能够将 RFC 6066 样式的
status_request
ClientHello
扩展发送到支持服务器。它必须能够正确解析ServerHello
握手消息中相同的hello扩展,并正确解析后续的CertificateStatus
握手消息内容。 -
客户端实现必须能够将 RFC 6961 样式的
status_request_v2
ClientHello
扩展发送到支持服务器。它必须能够在 hello 扩展中断言ocsp
或键入(或两者)。ocsp_multi
它必须能够正确解析ServerHello
握手消息中相同的hello扩展,并正确解析后续的CertificateStatus
握手消息内容。 -
服务器实现必须能够接收
status_request
握手消息status_request_v2
中的扩展ClientHello
并查询适当的 OCSP 响应程序。它必须能够将 OCSP 响应放入CertificateStatus
要返回给客户端的 TLS 握手消息中。 -
服务器实现必须能够缓存有效的 OCSP 响应,以便与不在其
status_request[_v2]
hello 扩展中发出带有随机数扩展请求的客户端重用。 -
客户端必须能够与至少两个能够执行 OCSP 装订的不同 Web 服务器(例如 Apache 2.4+)进行互操作。
-
服务器必须能够与至少两个能够断言
status_request
或 的不同客户端实现进行互操作status_request_v2
。此时,大多数主流浏览器(Firefox、Chrome 等)都可以生成status_request
hello 扩展,其他工具(例如 OpenSSL 的s_client
.出于自动化测试的目的,可以创建小型应用程序来链接 NSS 和 OpenSSL 库,以通过 OCSP 装订建立 TLS 连接。
风险和假设
通过此实现,JDK 中的 java 客户端将默认启用 OCSP 装订功能。但是,无法接受 TLSstatus_request
或TLS 扩展的 TLS 服务器存在潜在的互操作性问题status_request_v2
。已定义系统或安全属性以在必要时禁用 OCSP 装订。