gpt4 book ai didi

java - SSL 握手异常 :no cipher suites in common

转载 作者:太空宇宙 更新时间:2023-11-03 14:25:19 42 4
gpt4 key购买 nike

我已经看到其他关于此错误的问题,但大多数都没有使用 Spring Integration。我看到确实使用 Spring Integration 的那个是由于损坏的 keystore 。我已经多次重新创建我的 keystore 和信任库,所以这似乎不是问题所在。

我正在尝试在我的 TcpNetClientConnectionFactoryTcpNetServerConnectionFactory 之间启用 TLS。这是我的 Spring 配置:

@Bean
public TcpNetClientConnectionFactory clientConnectionFactory() {
TcpNetClientConnectionFactory factory = new TcpNetClientConnectionFactory("localhost", 6000);
factory.setTcpSocketFactorySupport(sslSocketFactorySupport(
"security/empty.jks",
"security/client-truststore.jks",
"changeit",
"changeit"));
factory.setTcpSocketSupport(new DefaultTcpSocketSupport());
factory.setSerializer(TcpCodecs.lengthHeader2());
factory.setDeserializer(TcpCodecs.lengthHeader2());
return factory;
}

@Bean
TcpNetServerConnectionFactory serverConnectionFactory() {
TcpNetServerConnectionFactory factory = new TcpNetServerConnectionFactory(6000);
factory.setTcpSocketFactorySupport(sslSocketFactorySupport(
"security/server.jks",
"security/empty.jks",
"changeit",
"changeit"));
factory.setTcpSocketSupport(new DefaultTcpSocketSupport());
factory.setSerializer(TcpCodecs.lengthHeader2());
factory.setDeserializer(TcpCodecs.lengthHeader2());
return factory;
}

@Bean
public DefaultTcpNetSSLSocketFactorySupport sslSocketFactorySupport(String keyStore, String trustStore, String keyStorePassword, String trustStorePassword) {
TcpSSLContextSupport contextSupport = new DefaultTcpSSLContextSupport(keyStore, trustStore, keyStorePassword, trustStorePassword);
return new DefaultTcpNetSSLSocketFactorySupport(contextSupport);
}

@Bean
public IntegrationFlow requestFlow() {
return IntegrationFlows
.from(Tcp.inboundAdapter(serverConnectionFactory()))
.<byte[]>handle((p, h) -> MessageBuilder
.withPayload(p)
.build())
.handle(Tcp.outboundAdapter(serverConnectionFactory()))
.get();
}

@Bean
public IntegrationFlow responseFlow() {
return IntegrationFlows
.from(Tcp.inboundAdapter(clientConnectionFactory()))
.channel(MessageChannels
.queue("responseChannel")
.get())
.get();
}

empty.jks 文件是一个空的 keystore 。以下是我用来生成服务器 keystore 和客户端信任库的命令:

#!/bin/bash

keytool -genkey \
-keypass changeit \
-storepass changeit \
-keystore src/main/resources/security/server.jks

keytool -export \
-storepass changeit \
-file src/main/resources/security/server.cer \
-keystore src/main/resources/security/server.jks

keytool -import \
-v \
-trustcacerts \
-file src/main/resources/security/server.cer \
-keypass changeit \
-storepass changeit \
-keystore src/main/resources/security/client-truststore.jks

最后,这是一个在我的两个连接工厂之间来回发送 Message 的简单测试。没有 TLS,它工作正常。借助 TLS,我获得了有关密码套件的 SSL 读取异常。

@Autowired
private TcpNetClientConnectionFactory client;

@Autowired
private QueueChannel responseChannel;

@Test
public void requestAndResponse() throws Exception {
Message<byte[]> request = MessageBuilder
.withPayload("foo".getBytes())
.build();

client.getConnection().send(request);

assertNotNull(responseChannel.receive(1000));
}

我的 SSL 设置有什么问题?

更新

我使用的是 Java 8。这是客户端密码:

TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_EMPTY_RENEGOTIATION_INFO_SCSV

服务器密码:

TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CB    C_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA    _WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_12    8_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_E    CDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AE    S_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_    SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_EMPTY_RENEGOTIATION_INFO_SCSV

我可以立即看出第一个匹配。

更新 2

使用 javax.net.debug=all,这是 ClientHello:

*** ClientHello, TLSv1.2
RandomCookie: GMT: 1567538676 bytes = { 28, 158, 236, 83, 48, 241, 225, 168, 30, 197, 146, 201, 129, 246, 199, 156, 9, 78, 61, 157, 11, 64, 25, 26, 41, 181, 233, 45 }
Session ID: {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }

我看到了 ClientHello 的原始写入(204 字节),然后是 5 字节的原始读取,然后是 199 字节。有趣的是,原始读取格式化后,它似乎是另一个 ClientHello,而不是 ServerHello:

pool-1-thread-2, READ: TLSv1.2 Handshake, length = 199
C0 0A C0 14 .(.=.&*** ClientHello, TLSv1.2
RandomCookie: GMT: 1567539109 bytes = { 119, 78, 120, 53, 121, 162, 190, 126, 136, 74, 228, 139, 71, 227, 132, 120, 177, 116, 234, 187, 14, 134, 253, 158, 109, 174, 41, 17 }
Session ID: {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }

紧随其后的是:

pool-1-thread-2, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure
pool-1-thread-2, WRITE: TLSv1.2 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 03 00 02 02 28 ......(
pool-1-thread-2, called closeSocket()
pool-1-thread-2, handling exception: javax.net.ssl.SSLHandshakeException: no cipher suites in common
pool-1-thread-2, called close()
pool-1-thread-2, called closeInternal(true)
2019-09-04 08:48:21.637 ERROR 1755 --- [pool-1-thread-2] o.s.i.i.tcp.connection.TcpNetConnection : Read exception localhost:63727:6000:51c3e8e9-194c-4f56-b238-960fa3b7c05c SSLHandshakeException:no cipher suites in common

知道为什么第二个 Hello 是另一个 ClientHello,而不是 ServerHello 吗?

最佳答案

这原来是应用程序上下文问题。我在 src/test/java 下定义服务器 SSL 配置。我的 Autowired 字段之一是从 src/main/java 拉取客户端 SSL 配置 bean,而不是我认为的服务器 bean。因此有两个 ClientHellos。

添加了几个@Qualifiers 以确保我的服务器配置在我认为的地方 Autowiring

关于java - SSL 握手异常 :no cipher suites in common,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57778558/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com