java - CamelJettyWebSocketServer, fatal error : 42: null cert chain

标签 java ssl apache-camel

我尝试在自定义 camel 端点中建立相互验证的连接。我尝试运行测试。当我将 ClientAuthentication.REQUIRE 设置为 NONE 时,建立了 TLS 连接,一切正常。不过,我想在连接上进行相互认证。当我将标志设置为 REQUIRE 时,我得到(启用完整调试输出):

CamelJettyWebSocketServer-40, fatal error: 42: null cert chain javax.net.ssl.SSLHandshakeException: null cert chain

让我困惑的是:当我不激活客户端认证时,客户端和服务器端都建立了一个网络套接字连接并进行单向认证。所以证书和信任链似乎没问题?

我的证书链是这样设置的:根 CA -> 子 CA -> 客户端和服务器证书。 因此,包含 RootCA 和 SubCA 证书的信任库在服务器端和客户端都是相同的,只有 keystore 不同。

这是日志的最后一部分(去除了原始数据):

* ServerHello, TLSv1.2 RandomCookie: GMT: 1478504471 bytes = ... 192, 99, 62} Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 Compression Method: 0 Extension renegotiation_info, renegotiated_connection: * %% Initialized: [Session-2, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384] ** TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 [read] MD5 and SHA1 hashes: len = 81 0000: ...
. *** Certificate chain chain [0] = [ [ Version: V3 Subject: CN=dptmt idl Server, OU=dptmt, O=company, L=Muenchen, ST=Bayern, C=DE Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

Key: Sun RSA public key, 2048 bits modulus: ... public exponent: 65537 Validity: [From: Tue Oct 25 11:50:28 CEST 2016, To: Thu Oct 25 11:50:28 CEST 2018] Issuer: CN=idl SubCA 2016, O=company, C=DE SerialNumber: [ 01]

Certificate Extensions: 8 1: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false AuthorityInfoAccess [ [ accessMethod: cklmsuers accessLocation: URIName: http://downloads.dptmt.company.de/rootcacert2016.cert ] ]

[2]: ObjectId: 2.5.29.35 Criticality=false AuthorityKeyIdentifier [ KeyIdentifier [ 0000: F3 85 C5 44 9F 10 A7 BE AF 8E 6C 54 73 07 31 CB ...D......lTs.1. 0010: FB 4F 73 81
.Os. ] ]

[3]: ObjectId: 2.5.29.19 Criticality=false BasicConstraints:[
CA:false PathLen: undefined ]

[4]: ObjectId: 2.5.29.31 Criticality=false CRLDistributionPoints [
[DistributionPoint: [URIName: http://crl.dptmt.company.de/idl.crl] ]]

[5]: ObjectId: 2.5.29.37 Criticality=false ExtendedKeyUsages [
clientAuth serverAuth ]

[6]: ObjectId: 2.5.29.15 Criticality=false KeyUsage [
DigitalSignature Key_Encipherment ]

[7]: ObjectId: 2.5.29.17 Criticality=false SubjectAlternativeName [
DNSName: localhost DNSName: 127.0.0.1 DNSName: idlconnector.dptmt.company.de ]

[8]: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: C8 39 51 89 74 35 FF AB 07 38 12 79 C0 AA 8C 17 .9Q.t5...8.y.... 0010: 22 D3 81 34
"..4 ] ]

] Algorithm: [SHA256withRSA]...

] *** Found trusted certificate: [ [ Version: V3 Subject: CN=idl SubCA 2016, O=company, C=DE Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

Key: Sun RSA public key, 2048 bits modulus: ... public exponent: 65537 Validity: [From: Tue Oct 25 11:49:47 CEST 2016, To: Wed Oct 23 11:49:47 CEST 2024] Issuer: CN=idl Root CA 2016, O=company, C=DE SerialNumber: [ 01]

Certificate Extensions: 6 1: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false AuthorityInfoAccess [ [ accessMethod: cklmsuers accessLocation: URIName: http://downloads.dptmt.company.de/rootcacert2016.cert ] ]

[2]: ObjectId: 2.5.29.35 Criticality=false AuthorityKeyIdentifier [ KeyIdentifier [ 0000: 7B 98 1D B2 FF 81 B4 DB D8 C2 5F 1D 88 8A AD 1A .........._..... 0010: 52 2D 60 2C
R-`, ] ]

[3]: ObjectId: 2.5.29.19 Criticality=true BasicConstraints:[ CA:true PathLen:2147483647 ]

[4]: ObjectId: 2.5.29.31 Criticality=false CRLDistributionPoints [
[DistributionPoint: [URIName: http://crl.dptmt.company.de/idl.crl] ]]

[5]: ObjectId: 2.5.29.15 Criticality=false KeyUsage [
DigitalSignature Key_CertSign Crl_Sign ]

[6]: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: F3 85 C5 44 9F 10 A7 BE AF 8E 6C 54 73 07 31 CB ...D......lTs.1. 0010: FB 4F 73 81
.Os. ] ]

] Algorithm: [SHA256withRSA] Signature: ...

] [read] MD5 and SHA1 hashes: len = 1156 0000: 0B ...
F..T * ECDH ServerKeyExchange Signature Algorithm SHA512withRSA Server key: Sun EC public key, 256 bits public x coord: 28847400382242897438936230468661390225193273270317541849731947641016598202380 public y coord: 44672647556933576846980891280419719564112470643460642037901420136126664747387 parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7) [read] MD5 and SHA1 hashes: len = 333 0000: ... CertificateRequest Cert Types: RSA, DSS, ECDSA Supported Signature Algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA Cert Authorities: [read] MD5 and SHA1 hashes: ... ServerHelloDone [read] MD5 and SHA1 hashes: len = 4 0000: 0E 00 00 00 .... Warning: no suitable certificate found - continuing without client authentication * Certificate chain


* ECDHClientKeyExchange ECDH Public value: { ... Finished verify_data: { 99, 243, 110, 215, 154, 6, 238, 190, 185, 65, 205, 89 } [write] MD5 and SHA1 hashes: len = 16 0000: 14 00 00 0C 63 F3 6E D7 9A 06 EE BE B9 41 CD 59 ....c.n......A.Y Padded plaintext before ENCRYPTION: len = 96 0000: ...
LC 08:41:11.655 [CamelJettyWebSocketServer-31-selector-ServerConnectorManager@3fcdcf/0] DEBUG org.eclipse.jetty.io.SelectorManager - Selector loop woken up from select, 1/1 selected 08:41:11.655 [CamelJettyWebSocketServer-31-selector-ServerConnectorManager@3fcdcf/0] DEBUG org.eclipse.jetty.io.SelectChannelEndPoint - Key interests updated 1 -> 0 on SelectChannelEndPoint@37823e21{/127.0.0.1:37052<->9292,Open,in,out,R,-,177/30000,SslConnection}{io=1,kio=0,kro=1} 08:41:11.655 [CamelJettyWebSocketServer-31-selector-ServerConnectorManager@3fcdcf/0] DEBUG org.eclipse.jetty.io.SelectChannelEndPoint - Local interests updating 1 -> 0 for SelectChannelEndPoint@37823e21{/127.0.0.1:37052<->9292,Open,in,out,R,-,177/30000,SslConnection}{io=0,kio=0,kro=1} 08:41:11.655 [CamelJettyWebSocketServer-31-selector-ServerConnectorManager@3fcdcf/0] DEBUG org.eclipse.jetty.io.SelectorManager - Queued change org.eclipse.jetty.io.SelectChannelEndPoint$1@431394e9 08:41:11.655 [CamelJettyWebSocketServer-31-selector-ServerConnectorManager@3fcdcf/0] DEBUG org.eclipse.jetty.io.AbstractConnection - FILL_INTERESTED-->FILLING SslConnection@3c4546fe{NEED_UNWRAP,eio=-1/-1,di=-1} -> HttpConnection@80ef4f3[FILL_INTERESTED,DecryptedEndPoint@4f49498{/127.0.0.1:37052<->9292,Open,in,out,R,-,178/30000,HttpConnection}->SelectChannelEndPoint@37823e21{/127.0.0.1:37052<->9292,Open,in,out,-,-,177/30000,SslConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of 0},g=HttpGenerator{s=START},c=HttpChannelOverHttp@40d049f5{r=0,c=false,a=IDLE,uri=}] 08:41:11.655 [CamelJettyWebSocketServer-31-selector-ServerConnectorManager@3fcdcf/0] DEBUG org.eclipse.jetty.io.ssl.SslConnection - onFillable enter DecryptedEndPoint@4f49498{/127.0.0.1:37052<->9292,Open,in,out,R,-,178/30000,HttpConnection}->SelectChannelEndPoint@37823e21{/127.0.0.1:37052<->9292,Open,in,out,-,-,177/30000,SslConnection}{io=0,kio=0,kro=1} 08:41:11.655 [CamelJettyWebSocketServer-31-selector-ServerConnectorManager@3fcdcf/0] DEBUG org.eclipse.jetty.io.AbstractConnection - FILL_INTERESTED-->FILLING HttpConnection@80ef4f3[FILLING,DecryptedEndPoint@4f49498{/127.0.0.1:37052<->9292,Open,in,out,-,-,178/30000,HttpConnection}->SelectChannelEndPoint@37823e21{/127.0.0.1:37052<->9292,Open,in,out,-,-,177/30000,SslConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of 0},g=HttpGenerator{s=START},c=HttpChannelOverHttp@40d049f5{r=0,c=false,a=IDLE,uri=}] 08:41:11.655 [CamelJettyWebSocketServer-31-selector-ServerConnectorManager@3fcdcf/0] DEBUG org.eclipse.jetty.io.ssl.SslConnection - onFillable exit DecryptedEndPoint@4f49498{/127.0.0.1:37052<->9292,Open,in,out,-,-,178/30000,HttpConnection}->SelectChannelEndPoint@37823e21{/127.0.0.1:37052<->9292,Open,in,out,-,-,177/30000,SslConnection}{io=0,kio=0,kro=1} 08:41:11.656 [CamelJettyWebSocketServer-31-selector-ServerConnectorManager@3fcdcf/0] DEBUG org.eclipse.jetty.io.AbstractConnection - FILLING-->IDLE SslConnection@3c4546fe{NEED_UNWRAP,eio=-1/-1,di=-1} -> HttpConnection@80ef4f3[FILLING,DecryptedEndPoint@4f49498{/127.0.0.1:37052<->9292,Open,in,out,-,-,178/30000,HttpConnection}->SelectChannelEndPoint@37823e21{/127.0.0.1:37052<->9292,Open,in,out,-,-,177/30000,SslConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of 0},g=HttpGenerator{s=START},c=HttpChannelOverHttp@40d049f5{r=0,c=false,a=IDLE,uri=}] 08:41:11.656 [CamelJettyWebSocketServer-31-selector-ServerConnectorManager@3fcdcf/0] DEBUG org.eclipse.jetty.io.SelectorManager - Running change org.eclipse.jetty.io.SelectChannelEndPoint$1@431394e9 08:41:11.656 [CamelJettyWebSocketServer-31-selector-ServerConnectorManager@3fcdcf/0] DEBUG org.eclipse.jetty.io.SelectorManager - Selector loop waiting on select 08:41:11.656 [CamelJettyWebSocketServer-40] DEBUG org.eclipse.jetty.server.HttpConnection - HttpConnection@80ef4f3[FILLING,DecryptedEndPoint@4f49498{/127.0.0.1:37052<->9292,Open,in,out,-,-,178/30000,HttpConnection}->SelectChannelEndPoint@37823e21{/127.0.0.1:37052<->9292,Open,in,out,-,-,177/30000,SslConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of 0},g=HttpGenerator{s=START},c=HttpChannelOverHttp@40d049f5{r=0,c=false,a=IDLE,uri=}] onFillable HttpChannelState@772152e{s=IDLE i=true a=null} 08:41:11.656 [CamelJettyWebSocketServer-40] DEBUG org.eclipse.jetty.io.ssl.SslConnection - SslConnection@3c4546fe{NEED_UNWRAP,eio=-1/-1,di=-1} -> HttpConnection@80ef4f3[FILLING,DecryptedEndPoint@4f49498{/127.0.0.1:37052<->9292,Open,in,out,-,-,179/30000,HttpConnection}->SelectChannelEndPoint@37823e21{/127.0.0.1:37052<->9292,Open,in,out,-,-,178/30000,SslConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of 0},g=HttpGenerator{s=START},c=HttpChannelOverHttp@40d049f5{r=0,c=false,a=IDLE,uri=}] fill enter 08:41:11.656 [CamelJettyWebSocketServer-40] DEBUG org.eclipse.jetty.io.ChannelEndPoint - filled 82 SelectChannelEndPoint@37823e21{/127.0.0.1:37052<->9292,Open,in,out,-,-,178/30000,SslConnection}{io=0,kio=0,kro=1} [Raw write]: length = 6 0000: 14 03 03 00 01 01
...... [Raw write]: length = 101 0000: ... 08:41:11.656 [CamelJettyWebSocketServer-40] DEBUG org.eclipse.jetty.io.ssl.SslConnection - SslConnection@3c4546fe{NEED_UNWRAP,eio=82/-1,di=-1} -> HttpConnection@80ef4f3[FILLING,DecryptedEndPoint@4f49498{/127.0.0.1:37052<->9292,Open,in,out,-,-,179/30000,HttpConnection}->SelectChannelEndPoint@37823e21{/127.0.0.1:37052<->9292,Open,in,out,-,-,0/30000,SslConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of 0},g=HttpGenerator{s=START},c=HttpChannelOverHttp@40d049f5{r=0,c=false,a=IDLE,uri=}] filled 82 encrypted bytes E5 28 74 84 36 9F 56 D8 11 0C 38 .f..L.(t.6.V...8 0060: 38 2C AC 97 6C
[Raw read]: length = 5 8,..l 0000: ... CamelJettyWebSocketServer-40, READ: TLSv1.2 Handshake, length = 77 08:41:11.666 [CamelJettyWebSocketServer-40] DEBUG org.eclipse.jetty.io.ssl.SslConnection - SslConnection@3c4546fe{NEED_TASK,eio=0/-1,di=-1} -> HttpConnection@80ef4f3[FILLING,DecryptedEndPoint@4f49498{/127.0.0.1:37052<->9292,Open,in,out,-,-,189/30000,HttpConnection}->SelectChannelEndPoint@37823e21{/127.0.0.1:37052<->9292,Open,in,out,-,-,10/30000,SslConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of 0},g=HttpGenerator{s=START},c=HttpChannelOverHttp@40d049f5{r=0,c=false,a=IDLE,uri=}] unwrap Status = OK HandshakeStatus = NEED_TASK bytesConsumed = 82 bytesProduced = 0 *
Certificate chain *** CamelJettyWebSocketServer-40, fatal error: 42: null cert chain javax.net.ssl.SSLHandshakeException: null cert chain %% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384]

可在此处找到已启用 SSL 调试的完整日志(包含 RAW 数据):Full Log

我的测试在这里定义:

public void startTestServer() throws Exception {
    // start a simple websocket echo service
    server = new Server(PORT);
    Connector connector = new ServerConnector(server);
    server.addConnector(connector);

    ServletContextHandler ctx = new ServletContextHandler();
    ctx.setContextPath("/");
    ctx.addServlet(TestServletFactory.class.getName(), "/*");

    server.setHandler(ctx);

    server.start();
    assertTrue(server.isStarted());      
}

public void stopTestServer() throws Exception {
    server.stop();
    server.destroy();
}

@Override
public void setUp() throws Exception {

    ClassLoader classLoader = getClass().getClassLoader();
    URL trustStoreURL = classLoader.getResource("jsse/client-truststore.jks");
    System.setProperty("javax.net.ssl.trustStore", trustStoreURL.getFile());
    System.setProperty("javax.net.ssl.trustStorePassword", "password");
    startTestServer();
    super.setUp();
}

@Override
public void tearDown() throws Exception {
    super.tearDown();
    stopTestServer();
}

@Test
public void testTwoRoutes() throws Exception {
    MockEndpoint mock = getMockEndpoint("mock:result");
    mock.expectedBodiesReceived(TEST_MESSAGE);

    template.sendBody("direct:input", TEST_MESSAGE);

    mock.assertIsSatisfied();
}

private static SSLContextParameters defineClientSSLContextClientParameters() {

    KeyStoreParameters ksp = new KeyStoreParameters();
    ksp.setResource(Thread.currentThread().getContextClassLoader().getResource("jsse/client-keystore.jks").toString());
    ksp.setPassword(PWD);

    KeyManagersParameters kmp = new KeyManagersParameters();
    kmp.setKeyPassword(PWD);
    kmp.setKeyStore(ksp);

    KeyStoreParameters tsp = new KeyStoreParameters();
    tsp.setResource(Thread.currentThread().getContextClassLoader().getResource("jsse/client-truststore.jks").toString());

    tsp.setPassword(PWD);

    TrustManagersParameters tmp = new TrustManagersParameters();
    tmp.setKeyStore(tsp);

    SSLContextServerParameters scsp = new SSLContextServerParameters();
    scsp.setClientAuthentication(ClientAuthentication.REQUIRE.name());
    //scsp.setClientAuthentication(ClientAuthentication.NONE.name());

    SSLContextParameters sslContextParameters = new SSLContextParameters();
    sslContextParameters.setKeyManagers(kmp);
    sslContextParameters.setTrustManagers(tmp);
    sslContextParameters.setServerParameters(scsp);


    return sslContextParameters;
}

private static SSLContextParameters defineServerSSLContextParameters() {
    KeyStoreParameters ksp = new KeyStoreParameters();
    ksp.setResource(Thread.currentThread().getContextClassLoader().getResource("jsse/server-keystore.jks").toString());
    ksp.setPassword(PWD);

    KeyManagersParameters kmp = new KeyManagersParameters();
    kmp.setKeyPassword(PWD);
    kmp.setKeyStore(ksp);

    KeyStoreParameters tsp = new KeyStoreParameters();
    tsp.setResource(Thread.currentThread().getContextClassLoader().getResource("jsse/server-truststore.jks").toString());
    tsp.setPassword(PWD);

    TrustManagersParameters tmp = new TrustManagersParameters();
    tmp.setKeyStore(tsp);

    SSLContextServerParameters scsp = new SSLContextServerParameters();
    scsp.setClientAuthentication(ClientAuthentication.REQUIRE.name());
    //scsp.setClientAuthentication(ClientAuthentication.NONE.name());

    SSLContextParameters sslContextParameters = new SSLContextParameters();
    sslContextParameters.setKeyManagers(kmp);
    sslContextParameters.setTrustManagers(tmp);
    sslContextParameters.setServerParameters(scsp);


   return sslContextParameters;
}

@Override
protected RouteBuilder[] createRouteBuilders() throws Exception {
    RouteBuilder[] rbs = new RouteBuilder[2];

    // A consumer
    rbs[0] = new RouteBuilder() {
        public void configure() {

            // Needed to configure TLS on the client side
            WsComponent wsComponent = (WsComponent) context.getComponent("someclient");
            wsComponent.setSslContextParameters(defineClientSSLContextClientParameters());

            from("direct:input").routeId("foo")
                .log(">>> Message from direct to WebSocket Client : ${body}")
                .to("someclient://localhost:9292/echo")
                .log(">>> Message from WebSocket Client to server: ${body}");
            }
    };

    // A provider
    rbs[1] = new RouteBuilder() {
        public void configure() {

                // Needed to configure TLS on the server side
                WebsocketComponent websocketComponent = (WebsocketComponent) context.getComponent("someserver");
                websocketComponent.setSslContextParameters(defineServerSSLContextParameters());

                // This route is set to use TLS, referring to the parameters set above
                from("someserver:localhost:9292/echo")
                .log(">>> Message from WebSocket Server to mock: ${body}")
                .to("mock:result");
        }
    };
    return rbs;
}

你能帮我了解一下发生了什么吗?

最佳答案

迟到的答案,但还是让我试试:

你写道:

“当我将 ClientAuthentication.REQUIRE 设置为 NONE 时,建立了 TLS 连接并且一切正常”

和:

“令我困惑的是:当我不激活客户端身份验证时,客户端和服务器端都建立了一个 web 套接字连接”

在我看来这里没有问题,这是预期的行为,不是吗?如果您要求客户端进行身份验证,那么您就有了连接。

如果您确实要求客户端进行身份验证并且客户端没有发送正确的证书链,那么您会得到一个 fatal error :42:空证书链在服务器端。

您可以使用 openssl 进行测试,但首先在服务器端使用 -Djavax.net.debug=all 启用 SSL 调试,然后执行:

openssl s_client -connect localhost:443 -CAfile cacert.pem -cert clientcert.pem -key clientkey.pem -state -tls1_2

您应该在 openssl 输出的末尾看到 Verify return code: 0 (ok)

在服务器端,将服务器日志的那部分复制到 srv-side-openssl-client-log.txt(例如)。

现在测试与您的 Java 客户端的连接,并将该服务器日志复制到 srv-side-java-client-log.txt

比较两者,看看有什么不同。您的 srv-side-java-client-log.txt 可能缺少一大块十六进制代码,因为它没有发送证书链。

关于java - CamelJettyWebSocketServer, fatal error : 42: null cert chain,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40461643/

相关文章:

java - Tomcat 9 上的 SSL Windows 认证错误

asp.net - SSL 身份验证导致 MVC 4 站点出现问题

java - 为什么在调用 Camel 路由的 CXF-RS 端点时会出现 NullpointerException?

java - Camel : java. lang.IllegalArgumentException:必须指定 defaultEndpoint

java - 如何停止camel http重试

java - 如何使用java分隔数组列表中的对象

java - 尝试从其他布局调用时不会调用 setContentView

java - JSP 表单不发送到数据库。使用 bean

java - 在 Java 中匹配简单正则表达式的问题

Docker TLS - 如何在本地机器上创建 key