我使用双向SSL成功运行Netty(请参阅Set up Netty with 2-way SSL Handsake (client and server certificate))。
但是,在我的一些处理程序中,我需要知道正在使用该应用程序的用户。我发现我无法弄清楚如何在我的处理程序中获取用户证书DN等信息。
我认为它可以在某个地方的ChannelHandlerContext中使用,但事实并非如此。有什么建议吗?
我知道SSLEngine可以在某处访问它,但我没有看到任何关于在SSLEngine公共API中获取访问权限的信息。我知道它在握手操作中具有访问权限....但我如何得到它?
答案 0 :(得分:9)
可以通过Pipline / ChannelHandlerContext
获取SSLEngineChannelHandlerContext 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);
}
}
答案 1 :(得分:8)
SSLEngine.getSession().getPeerCertificateChain()
。第0个条目是对等方自己的证书。
答案 2 :(得分:0)
我使用以下代码获取客户端证书和证书的颁发者。希望对您有所帮助。
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;
}