我已经尝试过Two way SSL authentication in Netty
,但是该示例不再显示任何信息,仅显示404 Not Found。我在这里找到了一些帮助:
尽管我的代码没有使用与sslchat完全相同的api调用(将管理者添加到init的顺序),但我的代码在执行所有操作后仍然失败。
这是我的代码和错误。该错误并不表示它是哪个ssl / tls错误。我仅使用一种身份验证和加密方法检查了两个证书/私钥(针对客户端/服务器的两个方面),并且可以正常工作。
服务器端代码:
KeyStore serverKeyStore = handleServerKeystore(sipListener);
KeyManagerFactory serverKmf = KeyManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore clientKeyStore = KeyStore.getInstance("JKS");
clientKeyStore.load(null, SipListener.KEYSTORE_PASSWORD.toCharArray());
for (ClientCertificate clientCertCert : sipListener.getClientCertificates()) {
Certificate clientCert = CertificateFactory.getInstance("X.509")
.generateCertificate(new ByteArrayInputStream(
clientCertCert.getClientCertificate().getBytes()));
clientKeyStore.setCertificateEntry(clientCertCert.getClientCertificateAlias(),
clientCert);
}
KeyStore.Builder serverBuilder = KeyStore.Builder.newInstance(serverKeyStore,
new KeyStore.PasswordProtection(SipListener.KEYSTORE_PASSWORD.toCharArray()));
KeyStore.Builder clientBuilder = KeyStore.Builder.newInstance(clientKeyStore,
new KeyStore.PasswordProtection(SipListener.KEYSTORE_PASSWORD.toCharArray()));
serverKmf.init(new KeyStoreBuilderParameters(
Arrays.asList(new KeyStore.Builder[] { serverBuilder, clientBuilder })));
// Initialize the SSLContext to work with our key managers.
SslContext serverContext = SslContextBuilder.forServer(serverKmf).build();
SSLEngine sslEngine = serverContext.newEngine(ch.alloc());
SSLParameters params = new SSLParameters();
List<SNIMatcher> matchers = new LinkedList<>();
SNIMatcher matcher = new SNIMatcher(0) {
@Override
public boolean matches(SNIServerName serverName) {
return true;
}
};
matchers.add(matcher);
params.setSNIMatchers(matchers);
sslEngine.setSSLParameters(params);
//sslEngine.setUseClientMode(false);
sslEngine.setNeedClientAuth(true);
cp.addFirst("ssl", new SslHandler(sslEngine));
//More codecs follow
客户端代码:
SslContextBuilder sslBuilder = SslContextBuilder.forClient();
SslContext cont2 = null;
KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore serverKeyStore = KeyStore.getInstance("BKS");
serverKeyStore.load(
new ByteArrayInputStream(
decoder.decode(sipSettingsBean.getSipSettingsServerBeans().get(0).getKeystoreB64().getBytes())),
SipListener.KEYSTORE_PASSWORD.toCharArray());
if (!serverKeyStore.isKeyEntry(sipSettingsBean.getSipSettingsServerBeans().get(0).getKeystoreAlias()))
throw new IllegalArgumentException(
"Server Keystore file has no matching key for given alias.");
keyManagerFactory.init(serverKeyStore,
SipListener.KEYSTORE_PASSWORD.toCharArray());
sslBuilder.keyManager(keyManagerFactory);
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
// truststore
KeyStore clientKeyStore = KeyStore.getInstance("BKS");
clientKeyStore.load(null, SipListener.KEYSTORE_PASSWORD.toCharArray());
for (Cert clientCertCert : sipSettingsBean.getSipSettingsServerBeans().get(0).getCerts()) {
Certificate clientCert = CertificateFactory.getInstance("X.509")
.generateCertificate(new ByteArrayInputStream(
clientCertCert.getCert().getBytes()));
clientKeyStore.setCertificateEntry(
clientCertCert.getAlias(), clientCert);
if (!clientKeyStore.isCertificateEntry(clientCertCert.getAlias()))
throw new IllegalArgumentException(
"Client Keystore file has no matching key for given alias.");
}
trustManagerFactory.init(clientKeyStore);
sslBuilder.trustManager(trustManagerFactory);
cont2 = sslBuilder.build();
SSLEngine engine = cont2.newEngine(ch.alloc(), toHostname,
portDestination);
engine.setEnabledProtocols(new String[]{"TLSv1.2"});
SSLParameters params = new SSLParameters();
List<SNIMatcher> matchers = new LinkedList<>();
SNIMatcher matcher = new SNIMatcher(0) {
@Override
public boolean matches(SNIServerName serverName) {
return true;
}
};
matchers.add(matcher);
params.setSNIMatchers(matchers);
engine.setSSLParameters(params);
ch.pipeline().addLast("ssl", new SslHandler(engine, false));
//More codecs follow
客户端错误:
2019-01-26 18:18:54.784 31491-31672/xx.xxxxxxxxxx.xxxxxxxxx D/no.tobiassenit.sipclient.network.RegisterAttemptSSL: request sent
2019-01-26 18:18:54.786 31491-31672/xx.xxxxxxxxxx.xxxxxxxxx D/no.tobiassenit.sipclient.network.RegisterAttemptSSL: request did not time out
2019-01-26 18:18:54.789 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: Read error: ssl=0x774f846f08: Failure in SSL library, usually a protocol error
2019-01-26 18:18:54.789 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: error:10000412:SSL routines:OPENSSL_internal:SSLV3_ALERT_BAD_CERTIFICATE (external/boringssl/src/ssl/tls_record.cc:592 0x774f890d08:0x00000001)
2019-01-26 18:18:54.789 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459)
2019-01-26 18:18:54.790 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
2019-01-26 18:18:54.790 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
2019-01-26 18:18:54.790 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
2019-01-26 18:18:54.790 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
2019-01-26 18:18:54.790 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
2019-01-26 18:18:54.790 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
2019-01-26 18:18:54.790 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
2019-01-26 18:18:54.790 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
2019-01-26 18:18:54.790 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
2019-01-26 18:18:54.791 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:646)
2019-01-26 18:18:54.791 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:581)
2019-01-26 18:18:54.791 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:498)
2019-01-26 18:18:54.791 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
2019-01-26 18:18:54.791 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
2019-01-26 18:18:54.791 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
2019-01-26 18:18:54.791 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at java.lang.Thread.run(Thread.java:764)
2019-01-26 18:18:54.792 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: Caused by: javax.net.ssl.SSLHandshakeException: Read error: ssl=0x774f846f08: Failure in SSL library, usually a protocol error
2019-01-26 18:18:54.792 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: error:10000412:SSL routines:OPENSSL_internal:SSLV3_ALERT_BAD_CERTIFICATE (external/boringssl/src/ssl/tls_record.cc:592 0x774f890d08:0x00000001)
2019-01-26 18:18:54.792 31491-31771/v W/System.err: at com.android.org.conscrypt.SSLUtils.toSSLHandshakeException(SSLUtils.java:331)
2019-01-26 18:18:54.792 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at com.android.org.conscrypt.ConscryptEngine.convertException(ConscryptEngine.java:1138)
2019-01-26 18:18:54.792 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:893)
2019-01-26 18:18:54.792 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:713)
2019-01-26 18:18:54.792 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:678)
2019-01-26 18:18:54.793 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at com.android.org.conscrypt.Java8EngineWrapper.unwrap(Java8EngineWrapper.java:236)
2019-01-26 18:18:54.793 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:294)
2019-01-26 18:18:54.793 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1275)
2019-01-26 18:18:54.793 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1177)
2019-01-26 18:18:54.793 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1221)
2019-01-26 18:18:54.793 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
2019-01-26 18:18:54.793 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
2019-01-26 18:18:54.793 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: ... 16 more
2019-01-26 18:18:54.794 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: Caused by: javax.net.ssl.SSLProtocolException: Read error: ssl=0x774f846f08: Failure in SSL library, usually a protocol error
2019-01-26 18:18:54.794 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: error:10000412:SSL routines:OPENSSL_internal:SSLV3_ALERT_BAD_CERTIFICATE (external/boringssl/src/ssl/tls_record.cc:592 0x774f890d08:0x00000001)
2019-01-26 18:18:54.794 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at com.android.org.conscrypt.NativeCrypto.ENGINE_SSL_read_direct(Native Method)
2019-01-26 18:18:54.794 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at com.android.org.conscrypt.NativeSsl.readDirectByteBuffer(NativeSsl.java:521)
2019-01-26 18:18:54.794 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at com.android.org.conscrypt.ConscryptEngine.readPlaintextDataDirect(ConscryptEngine.java:1099)
2019-01-26 18:18:54.794 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at com.android.org.conscrypt.ConscryptEngine.readPlaintextDataHeap(ConscryptEngine.java:1119)
2019-01-26 18:18:54.795 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at com.android.org.conscrypt.ConscryptEngine.readPlaintextData(ConscryptEngine.java:1091)
2019-01-26 18:18:54.795 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:841)
2019-01-26 18:18:54.795 31491-31771/xx.xxxxxxxxxx.xxxxxxxxx W/System.err: ... 25 more
服务器端错误:
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: null cert chain
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:646)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:581)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:498)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)Caused by: javax.net.ssl.SSLHandshakeException: null cert chain
at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1441)
at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535)
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:813)
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:781)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:294)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1275)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1177)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1221)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
... 16 moreCaused by: javax.net.ssl.SSLHandshakeException: null cert chain
at sun.security.ssl.Alerts.getSSLException(Alerts.java:201)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1672)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:309)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:297)
at sun.security.ssl.ServerHandshaker.clientCertificate(ServerHandshaker.java:1942)
at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:236)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:984)
at sun.security.ssl.Handshaker$1.run(Handshaker.java:924)
at sun.security.ssl.Handshaker$1.run(Handshaker.java:921)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1379)
at io.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1435)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1343)
... 20 more
|
当然:净值:4.1.28.Final,Win10和Java版本“ 1.8.0_151”
我尝试了netty 4.1.33.Final。结果相同。
您可能已经注意到,我已经忽略了引擎中主机名的测试。这可能仅用于服务器握手,而不用于客户端(专用密钥)握手。请提出建议,如果您也可以忽略握手的客户端主机名部分,除非它已经完成(我已经尝试过在两面都这样做),否则我的应用程序将无法支持该客户端的dns名称。 (它将能够为服务器提供支持,但暂时不支持它。)
我尝试过netty 4.1.34.Final-20190208.192045-20。结果相同。 我尝试了netty 4.1.34.Final。结果相同。 我尝试过netty 4.1.35.Final-SNAPSHOT。结果相同。
答案 0 :(得分:0)
我在用Netty执行双向SSL时遇到了这个问题。我通过使用以下配置解决了该问题:
public HttpClient getHttpClient(HttpClientProperties properties){
// configure pool resources
HttpClientProperties.Pool pool = properties.getPool();
ConnectionProvider connectionProvider;
if (pool.getType() == DISABLED) {
connectionProvider = ConnectionProvider.newConnection();
}
else if (pool.getType() == FIXED) {
connectionProvider = ConnectionProvider.fixed(pool.getName(),
pool.getMaxConnections(), pool.getAcquireTimeout());
}
else {
connectionProvider = ConnectionProvider.elastic(pool.getName());
}
HttpClient httpClient = HttpClient.create(connectionProvider)
.tcpConfiguration(tcpClient -> {
if (properties.getConnectTimeout() != null) {
tcpClient = tcpClient.option(
ChannelOption.CONNECT_TIMEOUT_MILLIS,
properties.getConnectTimeout());
}
// configure proxy if proxy host is set.
HttpClientProperties.Proxy proxy = properties.getProxy();
if (StringUtils.hasText(proxy.getHost())) {
tcpClient = tcpClient.proxy(proxySpec -> {
ProxyProvider.Builder builder = proxySpec
.type(ProxyProvider.Proxy.HTTP)
.host(proxy.getHost());
PropertyMapper map = PropertyMapper.get();
map.from(proxy::getPort).whenNonNull().to(builder::port);
map.from(proxy::getUsername).whenHasText()
.to(builder::username);
map.from(proxy::getPassword).whenHasText()
.to(password -> builder.password(s -> password));
map.from(proxy::getNonProxyHostsPattern).whenHasText()
.to(builder::nonProxyHosts);
});
}
return tcpClient;
});
HttpClientProperties.Ssl ssl = properties.getSsl();
if (ssl.getTrustedX509CertificatesForTrustManager().length > 0
|| ssl.isUseInsecureTrustManager()) {
httpClient = httpClient.secure(sslContextSpec -> {
// configure ssl
SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
X509Certificate[] trustedX509Certificates = ssl
.getTrustedX509CertificatesForTrustManager();
if (trustedX509Certificates.length > 0) {
sslContextBuilder.trustManager(trustedX509Certificates);
}
else if (ssl.isUseInsecureTrustManager()) {
sslContextBuilder
.trustManager(InsecureTrustManagerFactory.INSTANCE);
}
sslContextSpec.sslContext(sslContextBuilder)
.defaultConfiguration(ssl.getDefaultConfigurationType())
.handshakeTimeout(ssl.getHandshakeTimeout())
.closeNotifyFlushTimeout(ssl.getCloseNotifyFlushTimeout())
.closeNotifyReadTimeout(ssl.getCloseNotifyReadTimeout())
.handlerConfigurator(
(handler)->{
SSLEngine engine = handler.engine();
//engine.setNeedClientAuth(true);
SSLParameters params = new SSLParameters();
List<SNIMatcher> matchers = new LinkedList<>();
SNIMatcher matcher = new SNIMatcher(0) {
@Override
public boolean matches(SNIServerName serverName) {
return true;
}
};
matchers.add(matcher);
params.setSNIMatchers(matchers);
engine.setSSLParameters(params);
}
)
;
});
}
return httpClient;
}
以上代码段使用handlerConfigurator
类中存在的netty's Builder提供的SslProvider
自定义SslHandler
,以避免主机名匹配。