在内部 LAN 上连接到 https

Connecting to https on internal LAN

我想连接到内部 LAN 上的 https 可信站点。

我试过:

    public static void main(String args[]) throws IOException {

    OkHttpClient client = new OkHttpClient();

    RequestBody formBody = new FormBody.Builder()
            .add("user", "password")
            .build();

    Request request = new Request.Builder()
            .url("https://contoso.com")
            .post(formBody)
            .build();

    Response response = client.newCall(request).execute();
    System.out.println(response.code());

但这导致 PKIX Path Building Error,ValidatorException:无法找到请求目标的有效证书路径。

上面的link建议加上:

    System.setProperty("javax.net.ssl.trustStore", "cacerts");
    System.setProperty("javax.net.ssl.trustStorePassword", "password");

但这会产生一个新的错误:

javax.net.ssl.SSLException: javalang.RunTimeException: UnexpectedError: java.security.InvalidAlgoritmParameterException: the trustedAnchors parameter must be non empty

我还尝试通过执行 fatjar 来强制使用 cacerts:

java -jar TestClient.jar -Djava.net.ssl.trustStore="\path\to\cscerts\in\java\lib\security\cacerts"

但我最终还是得到“trustAnchors 参数必须为非空”

如果我尝试 https://www.google.com - 它工作正常。 Java 也设置为使用网络代理。

如何修复此错误以连接到此站点?

当你说“内部 LAN 上的可信站点”时,你似乎在谈论合作环境?!这些环境很可能是受管理的。因此,例如一家公司颁发根证书或 ca 并将其分发到您的系统信任库。

Java 有自己的信任库,很可能不受管理。因此,为了信任您的内部网站,您有多种选择。

  1. 使用您的系统信任库。当你在 windows 时,你可以设置一个系统 属性 -Djavax.net.ssl.trustStoreType=WINDOWS-ROOT
  2. 将您的内部服务的根证书添加到您的 java 信任库。
  3. 使用该证书创建一个新的信任库。
  4. 不验证证书并相信一切。

这在一定程度上取决于您的应用程序的目的以及它应该运行选择哪个选项。