java - 具有给定 PKCS12 的 Netty websocket 客户端示例

标签 java websocket netty pkcs#12

我有 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 中实现它。因此,查看示例代码,它只接受协议(protocol) wswss。而在上面的示例中,HTTPS 请求使用适当的 header 升级到 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();

关于java - 具有给定 PKCS12 的 Netty websocket 客户端示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59899941/

相关文章:

Java Stream 平均值的最大值

Java if else 语句改变字符串

java - groupBy 与结构失败的 collect_list

javascript - socket.io 服务器对象选项,两者之间有什么影响?

Netty:如何处理从 ChunkedFile 接收到的 block

java - ExtJS JsonStore 和 Netty

java - PreparedStatement 类型中的方法 setArray(int, Array) 不适用于参数 (String, String[])

java - 运行 chat.xhtml 示例返回 : Info: WebSocket closed

java - Spring Websocket升级请求处理

java - 在Java中读取little-endian 64位 float