Пример клиента netty websocket с заданным PKCS12 - PullRequest
0 голосов
/ 24 января 2020

У меня есть файл client.p12 и MyPassword , я пытаюсь установить sh соединение через веб-сокет, используя Код Netty, доступный здесь . В настоящее время у меня есть рабочий пример в 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 запрашивает обновление до WebSocket с использованием соответствующих заголовков. Поэтому я понимаю, что если я предоставлю доменное имя как «wss: ////api.server.com/messaging», то сначала оно установит sh соединение 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;
    }

1 Ответ

1 голос
/ 26 января 2020

SSlContextBuilder имеет метод, который принимает KeyManagerFactory:

SslContextBuilder.forClient()
    .keyManager(keyManagerFactory)
    .trustManager(InsecureTrustManagerFactory.INSTANCE)
    .build();
...