【问题标题】:Using a custom keystore with Jetty's WebSocketClientFactory将自定义密钥库与 Jetty 的 WebSocketClientFactory 一起使用
【发布时间】:2012-08-07 17:25:53
【问题描述】:

我有一个 Java 项目,它通过使用自签名证书的安全 WebSocket 传输连接到 CometD 服务器。我正在通过以下方式配置WebSocketClientFactory

wssFactory.getSslContextFactory().setKeyStorePath("/path/to/my/custom.jks");
wssFactory.getSslContextFactory().setKeyStorePassword("mypass");

然后像这样创建我的BayeuxClient

BayeuxClient client = new BayeuxClient(
        "wss://myserver.com/cometd",
        WebSocketTransport.create(clientOptions, wssFactory));

确实,当第一次加载时,似乎配置正确:

[DEBUG] 2012-08-07 12:58:05,786 : starting org.eclipse.jetty.websocket.WebSocketClientFactory@75cfa3d2
[DEBUG] 2012-08-07 12:58:05,786 : starting qtp2005556553{8<=0<=0/254,-1}
[DEBUG] 2012-08-07 12:58:05,788 : STARTED qtp2005556553{8<=7<=8/254,0}
[DEBUG] 2012-08-07 12:58:05,788 : starting org.eclipse.jetty.websocket.WebSocketClientFactory$WebSocketClientSelector@50c8c3b8
[DEBUG] 2012-08-07 12:58:05,795 : STARTED org.eclipse.jetty.websocket.WebSocketClientFactory$WebSocketClientSelector@50c8c3b8
[DEBUG] 2012-08-07 12:58:05,795 : Starting Thread[qtp2005556553-33 Selector0,5,main] on org.eclipse.jetty.io.nio.SelectorManager$1@346fe350
[DEBUG] 2012-08-07 12:58:05,797 : starting SslContextFactory@4240eca3(/Users/apetresc/Downloads/infrastructure.jks,null)
[INFO ] 2012-08-07 12:58:05,981 : Enabled Protocols [SSLv2Hello, SSLv3, TLSv1] of [SSLv2Hello, SSLv3, TLSv1]
[DEBUG] 2012-08-07 12:58:05,981 : Enabled Ciphers   [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] of [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV, SSL_RSA_WITH_NULL_MD5, SSL_RSA_WITH_NULL_SHA, SSL_DH_anon_WITH_RC4_128_MD5, TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_DH_anon_WITH_AES_256_CBC_SHA, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, TLS_KRB5_WITH_RC4_128_SHA, TLS_KRB5_WITH_RC4_128_MD5, TLS_KRB5_WITH_3DES_EDE_CBC_SHA, TLS_KRB5_WITH_3DES_EDE_CBC_MD5, TLS_KRB5_WITH_DES_CBC_SHA, TLS_KRB5_WITH_DES_CBC_MD5, TLS_KRB5_EXPORT_WITH_RC4_40_SHA, TLS_KRB5_EXPORT_WITH_RC4_40_MD5, TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5]
[DEBUG] 2012-08-07 12:58:05,981 : STARTED SslContextFactory@4240eca3(/Users/apetresc/Downloads/infrastructure.jks,/Users/apetresc/Downloads/infrastructure.jks)
[DEBUG] 2012-08-07 12:58:05,981 : STARTED org.eclipse.jetty.websocket.WebSocketClientFactory@75cfa3d2

而且,确实,实际上使用BayeuxClient 有效。但是,即使我根本没有指定密钥库,它也可以工作——它只是将其视为未签名的证书。而且,事实上,这似乎就是正在发生的事情,从我每隔几秒就会收到的错误日志来看:

[DEBUG] 2012-08-07 13:20:37,348 : State update: CONNECTED -> CONNECTED
[DEBUG] 2012-08-07 13:20:37,348 : Connecting, transport org.cometd.websocket.client.WebSocketTransport@53ddbcb1
[DEBUG] 2012-08-07 13:20:37,348 : [Session-1, SSL_NULL_WITH_NULL_NULL] SslConnection@79c190a2 SSL NOT_HANDSHAKING i/o/u=0/0/0 ishut=false oshut=false {WebSocketClientConnection p=WebSocketParserRFC6455@5266db4e state=START buffer= g=WebSocketGeneratorRFC6455@5ec80825 closed=false buffer=-1} NOT_HANDSHAKING filled=0/0 flushed=0/0
[DEBUG] 2012-08-07 13:20:37,348 : Sending messages [{id=50, connectionType=websocket, channel=/meta/connect, clientId=2u16ol79fcq7hqe1wu52pr0ws4aw}]
[DEBUG] 2012-08-07 13:20:37,348 : Registering WebSocketExchange {id=50, connectionType=websocket, channel=/meta/connect, clientId=2u16ol79fcq7hqe1wu52pr0ws4aw}
[DEBUG] 2012-08-07 13:20:37,348 : [Session-1, SSL_NULL_WITH_NULL_NULL] SslConnection@79c190a2 SSL NOT_HANDSHAKING i/o/u=0/0/0 ishut=false oshut=false {WebSocketClientConnection p=WebSocketParserRFC6455@5266db4e state=OPCODE buffer= g=WebSocketGeneratorRFC6455@5ec80825 closed=false buffer=-1} NOT_HANDSHAKING filled=0/0 flushed=0/0
[DEBUG] 2012-08-07 13:20:37,348 : Sending messages [{"id":"50","connectionType":"websocket","channel":"/meta/connect","clientId":"2u16ol79fcq7hqe1wu52pr0ws4aw"}]
[DEBUG] 2012-08-07 13:20:37,348 : [Session-1, SSL_NULL_WITH_NULL_NULL] SslConnection@79c190a2 SSL NOT_HANDSHAKING i/o/u=0/0/0 ishut=false oshut=false {WebSocketClientConnection p=WebSocketParserRFC6455@5266db4e state=OPCODE buffer= g=WebSocketGeneratorRFC6455@5ec80825 closed=false buffer=116} NOT_HANDSHAKING filled=0/0 flushed=0/0
[DEBUG] 2012-08-07 13:20:37,349 : [Session-1, SSL_NULL_WITH_NULL_NULL] SslConnection@79c190a2 SSL NOT_HANDSHAKING i/o/u=0/0/0 ishut=false oshut=false {WebSocketClientConnection p=WebSocketParserRFC6455@5266db4e state=OPCODE buffer=null g=WebSocketGeneratorRFC6455@5ec80825 closed=false buffer=116} NOT_HANDSHAKING filled=0/0 flushed=0/0
[DEBUG] 2012-08-07 13:20:37,349 : [Session-1, SSL_NULL_WITH_NULL_NULL] wrap OK NOT_HANDSHAKING consumed=116 produced=137
[DEBUG] 2012-08-07 13:20:37,349 : [Session-1, SSL_NULL_WITH_NULL_NULL] SslConnection@79c190a2 SSL NOT_HANDSHAKING i/o/u=0/0/0 ishut=false oshut=false {WebSocketClientConnection p=WebSocketParserRFC6455@5266db4e state=OPCODE buffer=null g=WebSocketGeneratorRFC6455@5ec80825 closed=false buffer=0} NOT_HANDSHAKING filled=0/0 flushed=137/0
[DEBUG] 2012-08-07 13:20:37,349 : [Session-1, SSL_NULL_WITH_NULL_NULL] SslConnection@79c190a2 SSL NOT_HANDSHAKING i/o/u=0/0/0 ishut=false oshut=false {WebSocketClientConnection p=WebSocketParserRFC6455@5266db4e state=OPCODE buffer=null g=WebSocketGeneratorRFC6455@5ec80825 closed=false buffer=0} NOT_HANDSHAKING filled=0/0 flushed=0/0
[DEBUG] 2012-08-07 13:20:37,349 : [Session-1, SSL_NULL_WITH_NULL_NULL] handle SslConnection@79c190a2 SSL NOT_HANDSHAKING i/o/u=0/0/0 ishut=false oshut=false {WebSocketClientConnection p=WebSocketParserRFC6455@5266db4e state=OPCODE buffer=null g=WebSocketGeneratorRFC6455@5ec80825 closed=false buffer=-1} progress=false

对我来说,这意味着 CometD 握手正在完成,但 SSL 握手尚未完成。不过,我不知道为什么会这样。一种类似的方法适用于我的 HTTPS 调用。只有WSS让我头疼。

还值得一提的是,我可以在各种不同的环境中重现这一点,包括 Android 应用程序和 Jetty servlet 容器内。

有没有人成功使用带有自签名证书的 WSS?想弄清楚我做错了什么?

【问题讨论】:

  • 简而言之,有没有人和我一样发现错误代码SSL_NULL_WITH_NULL_NULL 没有信息量? :)
  • SSL_NULL_WITH_NULL_NULL 几乎可以肯定是指空密码套件,它不提供任何身份验证或加密(并且永远不应该启用......)。
  • @Bruno:你能扩展一下吗?从日志输出来看,我的密码套件是 anything 但 NULL(它似乎有几十个条目)。

标签: java security ssl jetty cometd


【解决方案1】:

在第二个代码块中,您没有收到任何“错误”。这是未配置的SslContextFactory 的正常输出,它提供空密码套件和始终批准的证书验证程序。 更多信息请参见此处SslContextFactoryconfiguration

从日志来看,这两种情况都有效。

对于您的问题的更通用的答案,当您使用自签名证书时,您可能希望使用信任存储配置SslContextFactory,以便证书验证可以使用它来验证自签名证书。

除此之外,在我看来,您的代码设置正确。

【讨论】:

    【解决方案2】:

    我对@9​​87654321@ 了解不多,但据我了解,它用于客户端配置,您实际上是在尝试连接到配置有自签名证书的服务器,即它存储在客户端的custom.jks 文件中。

    在客户端接受自签名证书所需的不是设置其密钥库(用于从该端进行客户端证书身份验证),而是设置其信任库。

    尝试将setKeyStore* 替换为setTrustStore*

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-24
      • 1970-01-01
      • 1970-01-01
      • 2020-06-30
      相关资源
      最近更新 更多