2012-05-15 49 views
3

我正在研究基于服务器和基于客户端的应用程序,该应用程序需要双向SSL身份验证。 (客户端使用SSL证书验证服务器和服务器对客户端进行身份验证。)Netty中的双向SSL身份验证

我对Netty很陌生,对此几乎没有怀疑。

  1. 是使用Netty进行双向认证的可能吗?
  2. 通过向服务器和客户端的pipelinefactories添加另一个SslHandler可以简单地实现吗?
  3. 如果以上情况属实,我如何在ChannelConnected()方法中获取所需的SslHandler来执行SslHandshake?是否有可能通过调用管道再次调用ChannelConected()方法来调用第二次握手?
  4. 我有什么可以参考的例子吗?

我真的很感谢任何关于这方面的帮助,答案或正确的方向。

谢谢先进。

回答

11

是否可以使用Netty进行双向认证?

它可以简单地通过增加另一个SslHandler到服务器和客户端的pipelinefactories实现的?

如果以上是真的,我怎么能抢要求SslHandler在ChannelConnected()方法做SslHandshake?

创建SSLContext时,您需要正确设置密钥库和信任库。

是否有可能通过再次调用管道调用ChannelConected()方法的第二次握手?

从内存中,客户端和服务器验证在第一次握手中完成。

在客户端上,将客户端的私钥安装在密钥库中,并将服务器的公钥放在信任库中。

在服务器上,将服务器的私钥安装在密钥库中,并将客户端的公钥放在信任库中。

我有什么可以参考的例子吗?

  • 下面是一个example我做的WebSockets。它仅向您显示如何设置服务器密钥库。您将不得不添加信任库作为第二个参数serverContext.init(kmf.getKeyManagers(), null, null);

  • 以下是Scala中类似的example,其中包含信任存储区设置。

  • 关于如何设置SSLContext,下面是一个很好的java guide

希望这会有所帮助。

+1

您没有在scala示例中关闭信任库的输入流。另外,最好使用'Key/TrustManagerFactory.getDefaultAlgorithm()'而不是强制'SunX509',它不是TMF的默认JSSE,并且不适用于非Sun/Oracle的JRE(例如IBM)。 – Bruno

3

双向身份验证要求服务器和客户端都有另一个信任的证书。客户端需要生成一个私钥,将其存储在他的密钥库中,并由服务器的信任库所信任的人签名。

这不仅仅是你写的代码的问题。

1

SSL是一种表示层协议,SSL握手恰好在套接字连接建立之后并且应用层获得可用的套接字连接之前发生。无论您使用什么应用程序,如果您拥有SSL协议层,那么您可以通过SSL进行工作。

双向认证只是上面@EJP提到的配置问题。如果双方都可以建立并验证彼此的信任链,那么握手成功。请参阅netty配置手册以配置SSL信任库。

+0

SSL握手不一定会在连接建立后立即发生,它可能发生在一些纯文本通信后(例如,使用'STARTTLS'-like协议或HTTP代理'CONNECT')或重新协商后(通常为如果在第一次握手中没有请求,则获得一个客户端证书)。 – Bruno

+0

@布鲁诺但是,不是SSL会话建立过程的纯文本通信部分? – Drona

+0

实际上,握手真正开始之前通常是正常的应用协议(通过'Client Hello')。通常情况下,它发生在大部分应用程序请求/响应之后,但是原则上在更长时间的交换之后可能会发生。 – Bruno