如何在 JAX-WS 客户端和客户端证书身份验证上指定客户端证书

How to specify the client certificate on a JAX-WS client and client certificate authentication

我正在 Java 编写 JAX-WS 客户端程序。对 WebService 的访问受到客户端证书的保护。我知道客户端证书是正确的,因为只有导入客户端证书(在 Firefox 中)我才能在 Firefox 中获取 WSDL。

但是我在编写应该使用 WebService 的 java 应用程序时遇到了问题。我所做的如下:

  MyOwnService svc = new MyOwnService(getServerURL(), MYOWNSERVICE_QNAME);
...
...
private URL getServerURL() throws IOException {
  URL url = new URL((String) cfg.get(ConfigData.SERVER_URL));

  HttpsURLConnection con = (HttpsURLConnection) url.openConnection();

  try {
    con.setSSLSocketFactory(getFactory(new File("/etc/pki/wildfly/client.keystore"), "123456"));
  } catch (Exception exc) {
    throw new IOException("Client certificate error!", exc);
  }

  return url;
}

private SSLSocketFactory getFactory(File pKeyFile, String pKeyPassword ) 
  throws ... {

  KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
  KeyStore keyStore = KeyStore.getInstance("PKCS12");

  InputStream keyInput = new FileInputStream(pKeyFile);
  keyStore.load(keyInput, pKeyPassword.toCharArray());
  keyInput.close();

  keyManagerFactory.init(keyStore, pKeyPassword.toCharArray());

  SSLContext context = SSLContext.getInstance("TLS");
  context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());

  return context.getSocketFactory();
}

但这没有用。如果我 运行 这个我在 MyOwnService 构造函数

中得到以下异常
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty.

实现支持客户端认证的 JAX-WS 客户端的正确方法是什么?

忘记我上面的代码。似乎您唯一必须做的就是将密钥库指定为环境变量,例如:

-Djavax.net.ssl.keyStore=/etc/pki/wildfly/client.keystore -Djavax.net.ssl.keyStorePassword=123456

如果我这样做并指定正确的密钥库,它就会起作用。如果我指定一个无效的密钥库文件(其中包含一个 other/wrong certificate/key),它就不起作用 :) .

但我不确定如果密钥库包含多个 PrivateKeyEntry,Java 如何从密钥库中获得正确的 key/cert。指定 javax.net.ssl.keyStoreAlias 将无效。可能是 Java 尝试 PrivateKeyEntry 直到找到正确的...

但是:唯一要做的就是将正确的密钥库指定为环境变量。