【问题标题】:Make SSL client call in Tomcat using Tomcat's keystore使用 Tomcat 的密钥库在 Tomcat 中进行 SSL 客户端调用
【发布时间】:2012-04-04 01:57:33
【问题描述】:

我有一个在 Tomcat 中运行的 Web 应用程序,它正在对另一个系统进行 Web 服务调用。我需要使用 SSL 和客户端身份验证来保护这个调用。我托管的 Tomcat 已经正确配置了特定于环境的信任库和密钥库,因此我需要使用这些存储来保护我自己的调用。这就是我卡住的地方。

如何找到配置 Tomcat 以进行我自己的 SSL 调用的密钥库和信任库?或者更好的是,使用这些值生成正确配置的 SSLContext 或 SSLSocketFactory?

我尝试过的事情:

  1. 我尝试依赖 SSLContext.getDefault()。这似乎没有设置。

  2. 我尝试依赖系统属性:

    System.getProperty("javax.net.ssl.trustStore");
    System.getProperty("javax.net.ssl.trustStorePassword");
    System.getProperty("javax.net.ssl.trustStoreType");
    System.getProperty( "javax.net.ssl.keyStore");
    System.getProperty( "javax.net.ssl.keyStorePassword");
    System.getProperty("javax.net.ssl.keyStoreType");
    

但这似乎是一个脆弱的解决方案,因为 Tomcat 不必配置系统属性。在其中一个测试环境中,设置了信任库信息,但未设置密钥库变量。它们在 Tomcat 的 server.xml 中定义。

是否有一些我忽略的简单方法可以做到这一点?

更新:

This question is similar 并且其中一个答案指出 SSL 可以由 OpenSSL\APR 处理,因此这里的任何解决方案都将在很大程度上取决于 Tomcat 的配置方式。假设 JSSE,解决方案似乎是:

  • 确保通过系统属性配置 Tomcat。
  • 让商店位于服务器上的预定义位置。
  • 在您的战争中打包您自己的商店副本。

对于上述前两个,您必须确保安全策略允许访问这些文件。

这些真的是我尝试做的最佳实践吗?

【问题讨论】:

  • 请注意,一般来说,无法访问容器的 SSL 设置(尤其是其私钥)是一项安全功能,因为 Web 应用程序可能不完全受信任。您可能也对此感兴趣:stackoverflow.com/q/5162279/372643
  • 我怀疑这可能是一项安全功能,但奇怪的是,这些存储实际上很容易访问,具体取决于 Tomcat 的配置方式。我希望有一种方法可以将 servlet 标记为受信任之类的。
  • 如果您在启动 Tomcat 的脚本中配置系统属性(例如 catalina.sh 或其 Windows 等效项,请参见上面的第二个链接),您应该能够访问系统属性(假设您是未使用安全管理器或已配置为允许)。
  • 我不认为这是 Accessing SSL Private Key From a Servlet 的副本。虽然相关,但这是一个关于如何管理密钥/信任库的更普遍的问题。这篇文章比其他文章对我的帮助更大(针对我的特定问题)。我认为这个问题应该保留。

标签: java tomcat ssl keystore


【解决方案1】:

我认为除其他外,您还混淆了入站和出站 SSL 连接。 Server.xml 包含入站 SSL 设置。

在 Java 中使用出站 SSL 时,应在 Tomcat 的启动中明确设置 javax.net.ssl.trustStore* 和 javax.net.ssl.keyStore*。请记住,默认情况下,除非您编写自己的密钥管理器,否则密钥库只能包含一个私钥。

大多数著名的 Web 服务库使用标准 HTTP 库,这些库使用 HTTPConnection/HTTPSConnection 或 Jakatta HTTPClient,如果服务器请求,将提供来自密钥库的客户端证书。您不需要创建自己的 SSLContext。

如果您要终止入站 Web 服务调用,那么如果需要,我会使用带有 SSL 和客户端身份验证的 Apache HTTP Server。

为清楚起见进行编辑:javax.net.ssl.keyStore 指定的密钥库可以包含多个私钥/证书对,但除非您编写自己的 KeyManager,否则您将无法使用额外的私钥/证书。当您在 Tomcat 中终止入站 SSL 连接时,这可能会出现问题 - 您需要一个用于外部入站连接的私钥/证书和另一个用于出站连接的私钥/证书。

【讨论】:

  • 如果我没记错的话,如果您指定别名,您可以在 KeyStore 中拥有多个私钥。
  • 您可以拥有任意数量的私钥和个人证书。客户端在ClientHello 消息中指定它将信任谁,并且由服务器通过默认或安装的KeyManager 来查找客户端将接受的个人证书。 @Pith
  • @user207421 我不确定是什么规格。您正在阅读,但 TLS 客户端确实 not 指定它将在 ClientHello 消息中信任的证书 - 客户端(在本例中在 Tomcat 服务器中运行)将指定什么密码和它将使用的协议版本,但不是谁可以签署证书。听起来您混淆了服务器和客户端 - 服务器可以通过 Certificate Request (tools.ietf.org/html/rfc5246#page-53) 的 certificate_authorities 字段通知客户端它将接受哪些个人证书。
  • 我的观点仍然有效,如果您发出出站 SSL 请求并且服务器需要客户端身份验证,那么您只能拥有一个私钥,除非您实现 KeyManager。否则,SSL 客户端将为所有连接选择配置的KeyStore 中的第一个。
  • @pith 实际上,您可以拥有多个私钥和公钥/证书。别名可帮助您(没有/没有其他人)在您的代码中选择证书。
猜你喜欢
  • 1970-01-01
  • 2015-10-07
  • 2011-09-26
  • 2012-09-06
  • 2010-12-05
  • 2012-07-19
  • 2016-02-13
  • 2023-03-08
  • 1970-01-01
相关资源
最近更新 更多