- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一个用 java/netty 构建的 MITM 代理服务器。最近我遇到了一个 https url,为此我的代理获得了 SSL 握手失败,但是 curl
命令能够在 TLS 协议(protocol)中访问。在我的代理代码中,客户端 SSL 上下文使用 trust-all 信任管理器。下面是我如何创建客户端 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 url,我认为 url 本身应该没问题。那么,我怎样才能让它在 Java/netty 中工作呢?
顺便说一句,我不确定是否可以公开有问题的https url,所以我选择不公开以避免不必要的麻烦。
更新
从 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 url 做了两个测试,一个使用 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 握手并获得有效证书。
相关日志如下。
来自 Jersey 客户端测试:
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 测试中不存在。
最佳答案
事实证明,对等主机和端口对我来说很重要。此行解决了问题:
SSLEngine engine = context.createSSLEngine(host, 443);
关于java - 使用 java/netty 获得 handshake_failure,但使用 curl 成功获取相同的 https url,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29714455/
我需要您在以下方面提供帮助。近一个月来,我一直在阅读有关任务和异步的内容。 我想尝试在一个简单的 wep api 项目中实现我新获得的知识。我有以下方法,并且它们都按预期工作: public Htt
我的可执行 jar 中有一个模板文件 (.xls)。不需要在运行时我需要为这个文件创建 100 多个副本(稍后将唯一地附加)。用于获取 jar 文件中的资源 (template.xls)。我正在使用
我在查看网站的模型代码时对原型(prototype)有疑问。我知道这对 Javascript 中的继承很有用。 在这个例子中... define([], function () { "use
影响我性能的前三项操作是: 获取滚动条 获取偏移高度 Ext.getStyle 为了解释我的应用程序中发生了什么:我有一个网格,其中有一列在每个单元格中呈现网格。当我几乎对网格的内容做任何事情时,它运
我正在使用以下函数来获取 URL 参数。 function gup(name, url) { name = name.replace(/[\[]/, '\\\[').replace(/[\]]/,
我最近一直在使用 sysctl 来做很多事情,现在我使用 HW_MACHINE_ARCH 变量。我正在使用以下代码。请注意,当我尝试获取其他变量 HW_MACHINE 时,此代码可以完美运行。我还认为
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关闭 9 年前。 要求提供代码的问题必须表现出对所解决问题的最低限度的理解。包括尝试过的解决方案、为什么
由于使用 main-bower-files 作为使用 Gulp 的编译任务的一部分,我无法使用 node_modules 中的 webpack 来require 模块code> dir 因为我会弄乱当
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 5 年前。 Improve this qu
我使用 Gridlayout 在一行中放置 4 个元素。首先,我有一个 JPanel,一切正常。对于行数变大并且我必须能够向下滚动的情况,我对其进行了一些更改。现在我的 JPanel 上添加了一个 J
由于以下原因,我想将 VolumeId 的值保存在变量中: #!/usr/bin/env python import boto3 import json import argparse import
我正在将 MSAL 版本 1.x 更新为 MSAL-browser 的 Angular 。所以我正在尝试从版本 1.x 迁移到 2.X.I 能够成功替换代码并且工作正常。但是我遇到了 acquireT
我知道有很多关于此的问题,例如 Getting daily averages with pandas和 How get monthly mean in pandas using groupby但我遇到
This is the query string that I am receiving in URL. Output url: /demo/analysis/test?startDate=Sat+
我正在尝试使用 javascript 中的以下代码访问 Geoserver 层 var gkvrtWmsSource =new ol.source.ImageWMS({ u
API 需要一个包含授权代码的 header 。这就是我到目前为止所拥有的: var fullUrl = 'https://api.ecobee.com/1/thermostat?json=\{"s
如何获取文件中的最后一个字符,如果是某个字符,则删除它而不将整个文件加载到内存中? 这就是我目前所拥有的。 using (var fileStream = new FileStream("file.t
我是这个社区的新手,想出了我的第一个问题。 我正在使用 JSP,我成功地创建了 JSP-Sites,它正在使用jsp:setParameter 和 jsp:getParameter 具有单个字符串。
在回答 StoreStore reordering happens when compiling C++ for x86 @Peter Cordes 写过 For Acquire/Release se
我有一个函数,我们将其命名为 X1,它返回变量 Y。该函数在操作 .on("focusout", X1) 中使用。如何获取变量Y?执行.on后X1的结果? 最佳答案 您可以更改 Y 的范围以使其位于函
我是一名优秀的程序员,十分优秀!