具有给定 PKCS12 的 Netty websocket 客户端示例
Netty websocket client example with a given PKCS12
我有 client.p12 文件和 MyPassword,我正在尝试使用 Netty code available over here 建立 websocket 连接。目前我在 OkHttpClient 中有工作示例。但是我很难将其映射到 netty。
我的服务器给了我这个域来连接到“https://api.server.com”
在 OkHttpClient 中,以下代码有效
OkHttpClient client = getClient(info);
Request request = new Request.Builder().url("https://api.server.com" + "/messaging").build();
WebSocket webSocket = client.newWebSocket(request, listener);
getClient 代码如下:
public static OkHttpClient getClient(ConnectionInfo info) {
KeyStore appKeyStore = KeyStore.getInstance("PKCS12");
appKeyStore.load(new FileInputStream("client.p12"), "MyPassword".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(appKeyStore, info.getPassword().toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException(
"Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[] {trustManager}, null);
context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
OkHttpClient.Builder builder =
new OkHttpClient.Builder().sslSocketFactory(context.getSocketFactory(), trustManager);
builder.retryOnConnectionFailure(true);
return builder.build();
}
既然上面的代码工作正常,我正在尝试在 Netty 中实现它。所以查看示例代码,它只接受协议 ws
和 wss
。而在上面的例子中 HTTPS 请求使用适当的 headers 升级到 WebSocket。所以我的理解是,如果我提供的域名为 "wss:////api.server.com/messaging" 那么它将首先建立 https 连接,然后将其升级为 WebSocket。
现在我不知道如何设置证书和密码。
// I have created a keyStore as following
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File("client.p12"));
try {
keyStore.load(instream, "MyPassword".toCharArray());
} finally {
instream.close();
}
final boolean ssl = "wss".equalsIgnoreCase(scheme);
final SslContext sslCtx;
if (ssl) {
// How to specify the above keystore with this client?
sslCtx = SslContextBuilder.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE).build();
} else {
sslCtx = null;
}
SSlContextBuilder
有一个采用 KeyManagerFactory
:
的方法
SslContextBuilder.forClient()
.keyManager(keyManagerFactory)
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.build();
我有 client.p12 文件和 MyPassword,我正在尝试使用 Netty code available over here 建立 websocket 连接。目前我在 OkHttpClient 中有工作示例。但是我很难将其映射到 netty。
我的服务器给了我这个域来连接到“https://api.server.com”
在 OkHttpClient 中,以下代码有效
OkHttpClient client = getClient(info);
Request request = new Request.Builder().url("https://api.server.com" + "/messaging").build();
WebSocket webSocket = client.newWebSocket(request, listener);
getClient 代码如下:
public static OkHttpClient getClient(ConnectionInfo info) {
KeyStore appKeyStore = KeyStore.getInstance("PKCS12");
appKeyStore.load(new FileInputStream("client.p12"), "MyPassword".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(appKeyStore, info.getPassword().toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException(
"Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[] {trustManager}, null);
context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
OkHttpClient.Builder builder =
new OkHttpClient.Builder().sslSocketFactory(context.getSocketFactory(), trustManager);
builder.retryOnConnectionFailure(true);
return builder.build();
}
既然上面的代码工作正常,我正在尝试在 Netty 中实现它。所以查看示例代码,它只接受协议 ws
和 wss
。而在上面的例子中 HTTPS 请求使用适当的 headers 升级到 WebSocket。所以我的理解是,如果我提供的域名为 "wss:////api.server.com/messaging" 那么它将首先建立 https 连接,然后将其升级为 WebSocket。
现在我不知道如何设置证书和密码。
// I have created a keyStore as following
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File("client.p12"));
try {
keyStore.load(instream, "MyPassword".toCharArray());
} finally {
instream.close();
}
final boolean ssl = "wss".equalsIgnoreCase(scheme);
final SslContext sslCtx;
if (ssl) {
// How to specify the above keystore with this client?
sslCtx = SslContextBuilder.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE).build();
} else {
sslCtx = null;
}
SSlContextBuilder
有一个采用 KeyManagerFactory
:
SslContextBuilder.forClient()
.keyManager(keyManagerFactory)
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.build();