使用 2-way SSL Handskake(客户端和服务器证书)设置 Netty [英] Set up Netty with 2-way SSL Handskake (client and server certificate)

查看:24
本文介绍了使用 2-way SSL Handskake(客户端和服务器证书)设置 Netty的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在尝试使用 2 路 SSL 握手来设置 Netty,其中客户端和服务器都提供并验证证书.

I am now trying to set up Netty with a 2 way SSL handshake, where both the client and server present and verify certificates.

这似乎没有在 SslHandler 中实现.有没有人这样做?我想它会进入 SslHandler.handshake 操作并被委托给 javax.net.ssl.SSLEngine?

This does not appear to be implemented in SslHandler. Has anyone does this? I suppose it would go in the SslHandler.handshake operation and be delegated to javax.net.ssl.SSLEngine?

任何提示/技巧/预先存在的实现?

Any hints/tips/pre-existing implementations?

谢谢!

ANSWER(stackoverflow 不会让我以正常方式发布)我发现如果我在设置 SslHandler 之前在 SSLEngine 对象上设置了 needClientAuth 标志,问题就解决了!

ANSWER (stackoverflow won't let me post it the normal way) I found that if I set the needClientAuth flag on the SSLEngine object before setting up my SslHandler, that takes care of the problem!

推荐答案

这里是解决方案,基于 netty 项目中的 HttpSnoop 服务器示例.

Here is the solution, based on the HttpSnoop server example from the netty project.

设置客户端管道时,ssl引擎必须设置如下:

When setting up the client side pipeline, the ssl engine must be set as follows:

public ChannelPipeline getPipeline() throws Exception {
    // Create a default pipeline implementation.
    ChannelPipeline pipeline = pipeline();

    // Uncomment the following line if you want HTTPS
    SSLEngine engine = SecureChatSslContextFactory.getServerContext().createSSLEngine();
    engine.setUseClientMode(false);
    engine.setNeedClientAuth(true);
    pipeline.addLast("ssl", new SslHandler(engine));

    pipeline.addLast("decoder", new HttpRequestDecoder());
    pipeline.addLast("logger", new RequestAuditLogger());
    // Uncomment the following line if you don't want to handle HttpChunks.
    pipeline.addLast("aggregator", new HttpChunkAggregator(1048576));
    pipeline.addLast("outputLogger", new ResponseAuditLogger());
    pipeline.addLast("encoder", new HttpResponseEncoder());
    // Remove the following line if you don't want automatic content compression.
    pipeline.addLast("deflater", new HttpContentCompressor());
    pipeline.addLast("handler", new HttpSnoopServerHandler());
    return pipeline;
}
}

那么你的 SSLContext 必须修改如下,以设置除了密钥库(SecureChatSslContextFactory)之外的信任库:

Then your SSLContext must be modified as follows to set up a trust store in addition to a keystore (SecureChatSslContextFactory):

public final class SecureChatSslContextFactory {


private static Logger logger = LoggerFactory.getLogger(SecureChatSslContextFactory.class);

private static final String PROTOCOL = "TLS";
private static final SSLContext SERVER_CONTEXT;
private static final SSLContext CLIENT_CONTEXT;

static {

    SSLContext serverContext = null;
    SSLContext clientContext = null;

        // get keystore and trustore locations and passwords
    String keyStoreLocation = System.getProperty("javax.net.ssl.keyStore");
    String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
    String trustStoreLocation = System.getProperty("javax.net.ssl.trustStore");
    String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
    try {

        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(KeyStoreStreamManager.asInputStream(keyStoreLocation),
                keyStorePassword.toCharArray());

        // Set up key manager factory to use our key store
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(ks, keyStorePassword.toCharArray());

          // truststore
        KeyStore ts = KeyStore.getInstance("JKS");
        ts.load(KeyStoreStreamManager.asInputStream(trustStoreLocation),
                trustStorePassword.toCharArray());

        // set up trust manager factory to use our trust store
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ts);

        // Initialize the SSLContext to work with our key managers.
        serverContext = SSLContext.getInstance(PROTOCOL);
        serverContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

    } catch (Exception e) {
        throw new Error(
                "Failed to initialize the server-side SSLContext", e);
    }

    try {
        clientContext = SSLContext.getInstance(PROTOCOL);
        clientContext.init(null, SecureChatTrustManagerFactory.getTrustManagers(), null);
    } catch (Exception e) {
        throw new Error(
                "Failed to initialize the client-side SSLContext", e);
    }

    SERVER_CONTEXT = serverContext;
    CLIENT_CONTEXT = clientContext;
}

public static SSLContext getServerContext() {
    return SERVER_CONTEXT;
}

public static SSLContext getClientContext() {
    return CLIENT_CONTEXT;
}

private SecureChatSslContextFactory() {
    // Unused
}
}

这篇关于使用 2-way SSL Handskake(客户端和服务器证书)设置 Netty的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆