我有一个用java / netty构建的MITM代理服务器。最近我遇到了一个https url,我的代理获得了SSL握手失败但curl
命令能够访问TLS协议。在我的代理代码中,客户端SSL上下文使用信任所有信任管理器。下面是我如何创建客户端SSL上下文和SSL处理程序。
public static SSLContext createClientSslContext() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext context = SSLContext.getInstance("TLS");
// create a trust-all manager
TrustManager trustAllManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
log.debug("do nothing - getAcceptedIssuers");
return new X509Certificate[0];
}
};
context.init(null, new TrustManager[]{trustAllManager}, null);
return context;
}
private SslHandler createClientSslHandler() {
try {
SSLContext context = SslContextFactory.createClientSslContext();
SSLEngine engine = context.createSSLEngine();
engine.setUseClientMode(true);
engine.setEnabledProtocols(new String[]{"TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3"});
return new SslHandler(engine);
} catch (Exception e) {
log.error("Failed to create SslHandler with exception:", e);
return null;
}
}
我设置了javax.net.debug = all。以下是错误输出。
*** ClientHello, TLSv1.2
RandomCookie: GMT: 1429274460 bytes = { 38, 155, 211, 75, 172, 225, 176, 73, 59, 96, 150, 25, 105, 108, 225, 216, 178, 171, 40, 154, 59, 187, 206, 50, 87, 63, 46, 137 }
Session ID: {}
Cipher Suites: [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_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
***
[write] MD5 and SHA1 hashes: len = 193
0000: 01 00 00 BD 03 03 55 31 FF 5C 26 9B D3 4B AC E1 ......U1.\&..K..
0010: B0 49 3B 60 96 19 69 6C E1 D8 B2 AB 28 9A 3B BB .I;`..il....(.;.
0020: CE 32 57 3F 2E 89 00 00 38 C0 23 C0 27 00 3C C0 .2W?....8.#.'.<.
0030: 25 C0 29 00 67 00 40 C0 09 C0 13 00 2F C0 04 C0 %.).g.@...../...
0040: 0E 00 33 00 32 C0 08 C0 12 00 0A C0 03 C0 0D 00 ..3.2...........
0050: 16 00 13 C0 07 C0 11 00 05 C0 02 C0 0C 00 04 00 ................
0060: FF 01 00 00 5C 00 0A 00 34 00 32 00 17 00 01 00 ....\...4.2.....
0070: 03 00 13 00 15 00 06 00 07 00 09 00 0A 00 18 00 ................
0080: 0B 00 0C 00 19 00 0D 00 0E 00 0F 00 10 00 11 00 ................
0090: 02 00 12 00 04 00 05 00 14 00 08 00 16 00 0B 00 ................
00A0: 02 01 00 00 0D 00 1A 00 18 06 03 06 01 05 03 05 ................
00B0: 01 04 03 04 01 03 03 03 01 02 03 02 01 02 02 01 ................
00C0: 01 .
nioEventLoopGroup-15-0, WRITE: TLSv1.2 Handshake, length = 193
[Raw write]: length = 198
0000: 16 03 03 00 C1 01 00 00 BD 03 03 55 31 FF 5C 26 ...........U1.\&
0010: 9B D3 4B AC E1 B0 49 3B 60 96 19 69 6C E1 D8 B2 ..K...I;`..il...
0020: AB 28 9A 3B BB CE 32 57 3F 2E 89 00 00 38 C0 23 .(.;..2W?....8.#
0030: C0 27 00 3C C0 25 C0 29 00 67 00 40 C0 09 C0 13 .'.<.%.).g.@....
0040: 00 2F C0 04 C0 0E 00 33 00 32 C0 08 C0 12 00 0A ./.....3.2......
0050: C0 03 C0 0D 00 16 00 13 C0 07 C0 11 00 05 C0 02 ................
0060: C0 0C 00 04 00 FF 01 00 00 5C 00 0A 00 34 00 32 .........\...4.2
0070: 00 17 00 01 00 03 00 13 00 15 00 06 00 07 00 09 ................
0080: 00 0A 00 18 00 0B 00 0C 00 19 00 0D 00 0E 00 0F ................
0090: 00 10 00 11 00 02 00 12 00 04 00 05 00 14 00 08 ................
00A0: 00 16 00 0B 00 02 01 00 00 0D 00 1A 00 18 06 03 ................
00B0: 06 01 05 03 05 01 04 03 04 01 03 03 03 01 02 03 ................
00C0: 02 01 02 02 01 01 ......
[Raw read]: length = 5
0000: 15 03 03 00 02 .....
[Raw read]: length = 2
0000: 02 28 .(
nioEventLoopGroup-15-0, READ: TLSv1.2 Alert, length = 2
nioEventLoopGroup-15-0, RECV TLSv1 ALERT: fatal, handshake_failure
nioEventLoopGroup-15-0, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
nioEventLoopGroup-15-0, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
nioEventLoopGroup-15-0, called closeOutbound()
nioEventLoopGroup-15-0, closeOutboundInternal()
nioEventLoopGroup-15-0, SEND TLSv1 ALERT: warning, description = close_notify
nioEventLoopGroup-15-0, WRITE: TLSv1 Alert, length = 2
nioEventLoopGroup-15-0, called closeInbound()
nioEventLoopGroup-15-0, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
2015-04-17 23:53:16.246 [nioEventLoopGroup-15-0] ERROR ClientHandler#exceptionCaught(): Caught exception
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLException: Received fatal alert: handshake_failure
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:347) ~[netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:230) ~[netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:84) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.PausableChannelEventExecutor.invokeChannelRead(PausableChannelEventExecutor.java:86) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:389) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at com.company.proxy.handler.TrafficCounterHandler.channelRead(TrafficCounterHandler.java:29) [classes/:na]
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:84) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.PausableChannelEventExecutor.invokeChannelRead(PausableChannelEventExecutor.java:86) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:389) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:956) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:127) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:514) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:471) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:385) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:351) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.util.internal.chmv8.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1412) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.util.internal.chmv8.ForkJoinTask.doExec(ForkJoinTask.java:280) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.util.internal.chmv8.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:877) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.util.internal.chmv8.ForkJoinPool.scan(ForkJoinPool.java:1706) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.util.internal.chmv8.ForkJoinPool.runWorker(ForkJoinPool.java:1661) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.util.internal.chmv8.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:126) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
Caused by: javax.net.ssl.SSLException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) ~[na:1.7.0_80]
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1639) ~[na:1.7.0_80]
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1607) ~[na:1.7.0_80]
at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1776) ~[na:1.7.0_80]
at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1068) ~[na:1.7.0_80]
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:890) ~[na:1.7.0_80]
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:764) ~[na:1.7.0_80]
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624) ~[na:1.7.0_80]
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1071) ~[netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:938) ~[netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:891) ~[netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:316) ~[netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
... 23 common frames omitted
nioEventLoopGroup-15-0, called closeOutbound()
nioEventLoopGroup-15-0, closeOutboundInternal()
nioEventLoopGroup-15-0, called closeInbound()
nioEventLoopGroup-15-0, closeInboundInternal()
nioEventLoopGroup-15-0, closeOutboundInternal()
我已经尝试过JDK 7和JDK 8,但也没有给我带来任何好运。我还安装了无限强度的JCE政策,但也没有运气。鉴于curl
命令能够成功访问https网址,我认为网址本身应该没问题。那么,我怎样才能使它在Java / netty中运行?
更新
从curl -v
输出,我可以看到这一行:
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
密码TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
出现在ClientHello消息中,因此缺失密码不太可能是根本原因。
更新
我对同一个https网址进行了两次测试,一次使用jersey-client,另一次使用我自己的自定义netty客户端。以下是代码。
@Test
public void testHandshakeFailedUrlWithJersey() throws Exception {
String url = "https://cdn.prod.paperg.com/ajax/libs/require.js/2.1.10/require.js";
Client client = ClientBuilder.newClient();
Response response = null;
try {
response = client.target(url).request().get();
} catch (Exception e) {
e.printStackTrace();
}
log.info("Response - {}", response);
}
@Test
public void testHandshakeFailedUrlWithNetty() throws Exception {
String url = "https://cdn.prod.paperg.com/ajax/libs/require.js/2.1.10/require.js";
Bootstrap clientBootstrap = new Bootstrap();
EventLoopGroup clientGroup = new NioEventLoopGroup();
SSLContext context = SslContextFactory.createClientSslContext();
SSLEngine engine = context.createSSLEngine();
engine.setUseClientMode(true);
engine.setEnabledProtocols(new String[]{"TLSv1"});
final SslHandler sslHandler = new SslHandler(engine);
clientBootstrap.group(clientGroup)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast(CLIENT_SSL_HANDLER, sslHandler)
.addLast(HTTP_CLIENT_CODEC, new HttpClientCodec())
.addLast(HTTP_CONTENT_AGGREGATOR, new HttpObjectAggregator(MAX_HTTP_CONTENT_LENGTH))
.addLast(CLIENT_HANDLER, new ChannelHandlerAdapter(){
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
log.info("Received message");
}
});
}
});
String host = "cdn.prod.paperg.com";
InetSocketAddress inetSocketAddress = new InetSocketAddress(host, 443);
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_0,
HttpMethod.GET, url);
Channel channel = clientBootstrap.connect(inetSocketAddress).sync().channel();
channel.writeAndFlush(request);
}
事实证明,jersey-client测试能够获得有效的响应,但netty-client测试失败并出现相同的handshake_failure错误。顺便说一下,我用https://www.google.com
验证了netty-client测试代码,它能够成功完成SSL握手并获得有效证书。
以下是相关日志。
来自泽西客户测试:
trigger seeding of SecureRandom
done seeding SecureRandom
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
main, setSoTimeout(0) called
%% No cached client session
*** ClientHello, TLSv1
RandomCookie: GMT: 1429371593 bytes = { 30, 195, 29, 134, 181, 7, 17, 54, 187, 208, 156, 70, 39, 155, 224, 131, 105, 241, 174, 168, 211, 230, 57, 162, 17, 27, 183, 151 }
Session ID: {}
Cipher Suites: [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_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_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [host_name: cdn.prod.paperg.com]
***
main, WRITE: TLSv1 Handshake, length = 191
main, READ: TLSv1 Handshake, length = 61
*** ServerHello, TLSv1
RandomCookie: GMT: -1685243653 bytes = { 168, 78, 151, 192, 211, 185, 197, 74, 192, 90, 94, 113, 176, 188, 210, 43, 19, 253, 221, 73, 35, 104, 243, 6, 28, 79, 40, 190 }
Session ID: {}
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Compression Method: 0
Extension server_name, server_name:
Extension renegotiation_info, renegotiated_connection: <empty>
Extension ec_point_formats, formats: [uncompressed, ansiX962_compressed_prime, ansiX962_compressed_char2]
***
%% Initialized: [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
** TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
main, READ: TLSv1 Handshake, length = 2560
*** Certificate chain
来自netty-client测试:
trigger seeding of SecureRandom
done seeding SecureRandom
Using SSLEngineImpl.
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie: GMT: 1429371694 bytes = { 31, 45, 240, 255, 71, 215, 187, 150, 66, 220, 94, 118, 163, 1, 24, 38, 155, 158, 254, 201, 249, 203, 125, 96, 56, 225, 162, 247 }
Session ID: {}
Cipher Suites: [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_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_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***
nioEventLoopGroup-0-1, WRITE: TLSv1 Handshake, length = 163
nioEventLoopGroup-0-1, READ: TLSv1 Alert, length = 2
nioEventLoopGroup-0-1, RECV TLSv1 ALERT: fatal, handshake_failure
nioEventLoopGroup-0-1, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
nioEventLoopGroup-0-1, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
nioEventLoopGroup-0-1, called closeOutbound()
nioEventLoopGroup-0-1, closeOutboundInternal()
nioEventLoopGroup-0-1, SEND TLSv1 ALERT: warning, description = close_notify
nioEventLoopGroup-0-1, WRITE: TLSv1 Alert, length = 2
nioEventLoopGroup-0-1, called closeInbound()
nioEventLoopGroup-0-1, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
我从两个测试中看到的唯一区别是,jersey-client将此消息放在ClientHello中:
Extension server_name, server_name
在netty-client测试中不存在。
答案 0 :(得分:2)
事实证明,对等主机和端口在我的情况下很重要。这一行解决了这个问题:
SSLEngine engine = context.createSSLEngine(host, 443);
答案 1 :(得分:1)
好的,这就是为我解决了类似的问题(如果有其他人遇到这个问题)。
在Ubuntu上使用Webupd8软件包,我必须单独安装oracle-java8-unlimited-jce-policy
。这使得强加密成为美国出口限制的一部分。
去图。