Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 尝试在前端和后端之间建立安全连接时,Netty出现SSL/TLS错误(“无通用密码套件”)_Java_Ssl_Netty_Encryption - Fatal编程技术网

Java 尝试在前端和后端之间建立安全连接时,Netty出现SSL/TLS错误(“无通用密码套件”)

Java 尝试在前端和后端之间建立安全连接时,Netty出现SSL/TLS错误(“无通用密码套件”),java,ssl,netty,encryption,Java,Ssl,Netty,Encryption,我想保护后端和前端之间的TCP连接。我们使用Netty来建立一个TCP连接,它工作得非常好。现在,我们希望通过使用SSL/TLS来保护此连接。因此,我创建了一个证书请求: openssl req -newkey rsa:2048 -keyout key.pem -out request.pem -subj '/C=DE/O=XX/ST=XX/L=XX/O=XX/OU=XX/CN=someaddress.de/emailAddress=support@xxx.de' 证书随后由CA创建 密钥库是

我想保护后端和前端之间的TCP连接。我们使用Netty来建立一个TCP连接,它工作得非常好。现在,我们希望通过使用SSL/TLS来保护此连接。因此,我创建了一个证书请求:

openssl req -newkey rsa:2048 -keyout key.pem -out request.pem -subj '/C=DE/O=XX/ST=XX/L=XX/O=XX/OU=XX/CN=someaddress.de/emailAddress=support@xxx.de'
证书随后由CA创建

密钥库是通过以下方式创建的:

keytool -import -alias xxx -keystore xxx.keystore -file cert-xxx.pem 
后端带有Netty的服务器:

public StatefulTcpServer(MessageHandler messageHandler, int port, KeyStore keyStore, String keyStorePassword) {
    this.messageHandler = messageHandler;
    factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
    allChannels = new DefaultChannelGroup("clients");

    initTLS(keyStore, keyStorePassword);

    ServerBootstrap bootstrap = new ServerBootstrap(factory);

    bootstrap.setPipelineFactory(new ChannelPipelineFactory() {

        @Override
        public ChannelPipeline getPipeline() {
            ChannelPipeline pipeline = Channels.pipeline();
            if (sslContext != null) {
                SSLEngine sslEngine = sslContext.createSSLEngine();
                sslEngine.setUseClientMode(false);
                sslEngine.setEnabledCipherSuites(new String[] {
                    "TLS_RSA_WITH_AES_128_CBC_SHA"
                });
                pipeline.addLast("ssl", new SslHandler(sslEngine));
            }

            pipeline.addLast("compressor", new ZlibEncoder());
            pipeline.addLast("decompressor", new ZlibDecoder());

            pipeline.addLast("decoder", new JBossSerializationDecoder());
            pipeline.addLast("encoder", new JBossSerializationEncoder());

            pipeline.addLast("handler", StatefulTcpServer.this);
            return pipeline;
        }
    });

    bootstrap.setOption("child.tcpNoDelay", true);
    bootstrap.setOption("child.keepAlive", true);

    bootstrap.bind(new InetSocketAddress(port));
}

private void initTLS(KeyStore keyStore, String keyStorePassword) {
    try {
        if (keyStore != null) {
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(keyStore, keyStorePassword.toCharArray());
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
        }
    }
    catch (GeneralSecurityException e) {
        logger.error("TLS connection could not be established", e);
        sslContext = null;
    }
}
前端带有Netty的服务器:

public void init(String backendHost, int backendPort, int timeOutSecs, boolean useTLS,
                boolean acceptOnlyTrustworthyCertsForTLS) throws ConnectionFailedException {

    channelFactory = new NioClientSocketChannelFactory(Executors.newCachedThreadPool(),
                    Executors.newCachedThreadPool());

    if (useTLS) {
        initTLS(acceptOnlyTrustworthyCertsForTLS);
    }

    ClientBootstrap bootstrap = new ClientBootstrap(channelFactory);
    bootstrap.setPipelineFactory(new ChannelPipelineFactory() {

        @Override
        public ChannelPipeline getPipeline() {
            ChannelPipeline pipeline = Channels.pipeline();

            if (sslContext != null) {
                SSLEngine sslEngine = sslContext.createSSLEngine();
                sslEngine.setUseClientMode(true);
                sslEngine.setEnabledCipherSuites(new String[] {
                    "TLS_RSA_WITH_AES_128_CBC_SHA"
                });
                pipeline.addLast("ssl", new SslHandler(sslEngine));
            }

            pipeline.addLast("compressor", new ZlibEncoder());
            pipeline.addLast("decompressor", new ZlibDecoder());

            pipeline.addLast("decoder", new JBossSerializationDecoder());
            pipeline.addLast("encoder", new JBossSerializationEncoder());

            pipeline.addLast("handler", StatefulTcpBackendCommunicator.this);
            return pipeline;
        }
    });
    bootstrap.setOption("tcpNoDelay", true);
    bootstrap.setOption("keepAlive", true);

    channelFuture = bootstrap.connect(new InetSocketAddress(backendHost, backendPort));
    try {
        boolean connected = channelFuture.await(timeOutSecs * 1000);
        if (!connected || !channelFuture.isSuccess()) {
            throw new ConnectionFailedException();
        }
    }
    catch (InterruptedException e) {
        logger.error(e.getMessage(), e);
    }
}


private void initTLS(boolean acceptOnlyTrustworthyCertsForTLS) {
    try {
        TrustManager[] trustManagers;
        if (acceptOnlyTrustworthyCertsForTLS) {
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory
                            .getDefaultAlgorithm());
            trustManagerFactory.init((KeyStore) null);
            trustManagers = trustManagerFactory.getTrustManagers();
        }
        else {
            trustManagers = new TrustManager[] {
                new X509TrustManager() {

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }


                    @Override
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                        return;
                    }


                    @Override
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                        return;
                    }
                }
            };
        }

        sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustManagers, new SecureRandom());
    }
    catch (GeneralSecurityException e) {
        logger.error("TLS connection could not be established. TLS is not used!", e);
        sslContext = null;
    }
}
尝试在前端和后端之间建立连接时,我遇到一个异常:

javax.net.ssl.SSLHandshakeException: no cipher suites in common

不幸的是没有帮助。服务器的配置是否有问题?还是我使用了错误的证书类型?

您是否尝试过同时关闭服务器和前端的密码套件?可能是特定密码的问题。您还可以监视与WireShark的连接,以查看任何一方的行为是否与您预期的一样。如果我允许密码套件而不进行身份验证,则该操作有效。有什么想法吗?使用Eclipse debuggerl,后端中SSLContext的初始化工作似乎正常。我最终发现了问题:密钥库中缺少私钥。