【问题标题】:How can I get the Client Certificate in Netty Handler to identify user?如何在 Netty Handler 中获取客户端证书来识别用户?
【发布时间】:2012-04-04 09:25:14
【问题描述】:

我正在使用 2-way SSL 成功运行 Netty(请参阅 Set up Netty with 2-way SSL Handsake (client and server certificate))。

但是,在我的一些处理程序中,我需要了解正在使用该应用程序的用户。我发现我无法弄清楚如何在我的处理程序中获取用户证书 DN 之类的信息。

我认为它可以在某个地方的 ChannelHandlerContext 中使用,但事实并非如此。有什么建议吗?

我知道 SSLEngine 可以在某处访问它,但我没有看到任何有关在 SSLEngine 公共 API 中获取访问权限的信息。我知道它在握手操作中具有访问权限....但是我该如何获取呢?

【问题讨论】:

    标签: ssl certificate netty


    【解决方案1】:

    SSLEngine.getSession().getPeerCertificateChain()。第零项是对等方自己的证书。

    【讨论】:

    • 玩!框架后台使用netty,我想要SSL客户端证书,如何获取当前的SSLEngine??
    【解决方案2】:

    SSLEngine可以通过Pipline/ChannelHandlerContext获取

    ChannelHandlerContext ctx = ...
    SslHandler sslhandler = (SslHandler) ctx.channel().pipeline().get("ssl");
    sslhandler.engine().getSession().getPeerCertificateChain()[0].getSubjectDN());
    

    这允许您在处理程序对象中获取证书。请注意,执行此操作时需要完成 SSL 握手。否则你会得到一个

    javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    

    异常。为避免这种情况,您可以在处理程序中侦听 userEvent(在我们的例子中为 HandshakeCompletionEvent),如下所示:

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
        logger.info("userEventTriggered: {0}, Class: {1}", evt.toString(), evt.getClass());
    
        if (evt instanceof HandshakeCompletionEvent) {
            fetchCertificate(ctx);
        }
    } 
    

    【讨论】:

      【解决方案3】:

      我使用以下代码获取客户端证书和证书的颁发者。希望对你有帮助。

       SslHandler sslHandler = (SslHandler) ctx.channel().pipeline().get("ssl");
      
       X509Certificate issuer = convert(sslHandler.engine().getSession().getPeerCertificateChain()[sslHandler.engine().getSession().getPeerCertificateChain().length -1]);
      
       System.out.println("issuer: " + issuer);
      
      
        public static java.security.cert.X509Certificate convert(javax.security.cert.X509Certificate cert) {
          try {
              byte[] encoded = cert.getEncoded();
              ByteArrayInputStream bis = new ByteArrayInputStream(encoded);
              java.security.cert.CertificateFactory cf
                      = java.security.cert.CertificateFactory.getInstance("X.509");
              return (java.security.cert.X509Certificate)cf.generateCertificate(bis);
          } catch (java.security.cert.CertificateEncodingException e) {
          } catch (javax.security.cert.CertificateEncodingException e) {
          } catch (java.security.cert.CertificateException e) {
          }
          return null;
      }
      

      【讨论】:

      • 为什么?你已经有证书了。为什么要对其进行编码并重新解码? convert() 方法在这里毫无意义。
      猜你喜欢
      • 1970-01-01
      • 2012-04-10
      • 1970-01-01
      • 2014-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-13
      相关资源
      最近更新 更多