我正在开发一个支持 EPP 服务器 SSL 的程序,这里是基于 netty 官方示例的代码:
public void start(final int port, final String type) {
try {
ServerBootstrap boot = new ServerBootstrap();
boot.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
if (type.equals("EPP/SSL")) {
SslHandler sslHandler = new SslHandler(sslEngine);
ch.pipeline().addFirst(sslHandler);
}
ch.pipeline().addLast(new EppDecoder(),new EppHandler(service));
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
this.port = port;
boot.bind(this.port).sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
这就是我获取 keystore 和初始化 channel 的方式:
String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm");
if (null == algorithm) {
algorithm = "SunX509";
}
try {
KeyStore ks = KeyStore.getInstance("JKS");
String file = FileLocator.getPath(this.keystorePath);
FileInputStream fileInputStream = new FileInputStream(file);
ks.load(fileInputStream, this.keystorePassword.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
kmf.init(ks, this.keystorePassword.toCharArray());
SSLContext serverContext = SSLContext.getInstance("TLS");
serverContext.init(kmf.getKeyManagers(), null, null);
this.sslEngine = serverContext.createSSLEngine();
this.sslEngine.setUseClientMode(false);
} catch (Exception e) {
throw new Error("Failed to initialize the server-side SSLContext", e);
}
在此之后,我使用 verisign epp 工具对其进行调试。不幸的是,使用epp工具的源代码,我发现它失败了:
public static Socket createSocket ( String aHost, int aPort, int aTimeout,
SSLSocketFactory aSslSocketFactory ) throws UnknownHostException,
IOException, Exception {
if ( aHost == null || aHost.trim().length() == 0 ) {
throw new IllegalArgumentException(
"SecureSocket.createSocket(): host name is invalid" );
}
if ( aPort < 0 || aPort > 65535 ) {
throw new IllegalArgumentException( "Invlaid argument: aPort" );
}
if ( aTimeout < 0 ) {
aTimeout = 0;
}
SSLSocket socket =
(SSLSocket) aSslSocketFactory.createSocket( aHost, aPort );
if ( aTimeout > 0 ) {
socket.setSoTimeout( aTimeout );
}
socket.startHandshake();//failed here
return socket;
}
我使用 keytool 创建了认证文件并将其导入到 epp 客户端 keystore 中,但它似乎不起作用。当类型不是“EPP/SSL”时,源代码仍然有效。为什么 SSL 套接字握手失败?
最佳答案
您必须为每个连接创建一个新的 SSLEngine
。看起来您的代码创建了一个 SSLEngine
实例,然后将其用于所有 SSL 连接。它永远不会起作用。
初始化 SSL 连接的推荐方法是在 io.netty.handler.ssl
中使用 SslContext
:
public static void main(String[] args) throws Exception {
final SslContext sslCtx = SslContext.newServerContext(...);
ServerBootstrap b = ...;
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
if (type.equals("EPP/SSL")) {
SslHandler sslHandler = sslCtx.newHandler(ch.alloc());
ch.pipeline().addFirst(sslHandler);
}
...
}
});
...
}
关于java - 为基于 netty 的 EPPServer 添加 SSL 支持时,客户端 socket.startHandshake() 失败。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28341458/