Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
647 views
in Technique[技术] by (71.8m points)

ssl - Load java trust store at runtime - after jvm have been launched?

In my java application I need to send POST requests to a server sitting behind https. On the machine where my java application is running there is a java trust store in: /usr/local/comp.jks that contains the certificate for the server I need to interact with (its already imported).

The problem is that I cannot control how the JVM is started that will run my java application - e.g. by adding:

-Djavax.net.ssl.trustStore=/usr/local/comp.jks to the VM arguments.

Is it possible to load the trust store in the above path at runtime from my application after the JVM has started so I can authenticate against the https site?

I have only found guides on how to import certificates at runtime but that I cannot use - also since I don't have the password for /usr/local/comp.jks

Below my current implementation (in groovy):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import java.util.Base64;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;


public class HttpsClientImpl extends AbstractHttpClient  {
  private String username = null;
  private String password = null;

  public HttpsClientImpl (String username, String password)  {
    this.username=username;
    this.password=password;

  }

  @Override
  public String sendRequest(String request, String method) {
    System.setProperty( "javax.net.ssl.trustStore", "/usr/local/comp.jks" );
    URL url = new URL(request);
    HttpsURLConnection con = (HttpsURLConnection) url.openConnection()
    // Set auth
    byte[] name = (username + ":" + password).getBytes();
    String authStr = Base64.getEncoder().encodeToString(name);
    con.setRequestProperty("Authorization", "Basic " + authStr)

    con.setRequestMethod(method);
    writeResult(con);
    return con.getResponseCode();
  }


  private void writeResult(HttpsURLConnection con) throws IOException {
    if(con!=null){
      BufferedReader br = null;
      if (200 <= con.getResponseCode() && con.getResponseCode() <= 299) {
        br = new BufferedReader(new InputStreamReader(con.getInputStream()));
      } else {
        br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
      }
      try {
        String input;
        while ((input = br.readLine()) != null){
          System.out.println(input);
        }
        br.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
}

When I run that I get:

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
Caused: sun.security.validator.ValidatorException: PKIX path building failed
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Assuming you haven't instantiated any SSL connections yet, you can simply call

System.setProperty( "javax.net.ssl.trustStore", "/usr/local/comp.jks" );

You'll probably also need to set javax.net.ssl.trustStorePassword and maybe javax.net.ssl.trustStoreType.

If the default SSL infrastructure has alredy been instantiated, you'll probably have to create your own SSLContext and SSLSocketFactory using your keystore.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...