Use PEM Encoded CA Cert on filesystem directly for HTTPS request?

≯℡__Kan透↙ 提交于 2019-12-17 16:43:11

问题


This is similar to Import PEM into Java Key Store. But the question's answers use OpenSSL for conversions and tools to import them into key stores on the file system.

I'm trying to use a well formed X509 certificate as a trust anchor:

static String CA_FILE = "ca-rsa-cert.pem";

public static void main(String[] args) throws Exception
{
    KeyStore ks = KeyStore.getInstance("JKS");
    ks.load(new FileInputStream(CA_FILE), null);

    TrustManagerFactory tmf = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ks);

    SSLContext context = SSLContext.getInstance("TLS");
    context.init(null, tmf.getTrustManagers(), null);

    // Redirected through hosts file
    URL url = new URL("https://example.com:8443");

    HttpsURLConnection connection = (HttpsURLConnection) url
            .openConnection();
    connection.setSSLSocketFactory(context.getSocketFactory());

    ...
}

When I attempt to run the program, I get an error:

$ java TestCert 
Exception in thread "main" java.io.IOException: Invalid keystore format
    at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:650)
    at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
    at java.security.KeyStore.load(KeyStore.java:1214)
    at TestCert.main(TestCert.java:30)

I also tried KeyStore ks = KeyStore.getInstance("PEM"); and getInstance("X509");, but they did not work either.

I know Java supports PEM and DER encoded certificates because that's what a web server sends to a client. But none of the KeyStoreType's seem to match my needs, so I suspect I'm not using the right APIs for this.

The reasons I want to use them directly and not import them into a long-lived KeyStore are:

  1. There are hundreds of PEM certs to test
  2. The certs are on my filesystem
  3. Using certs from the filesystem matches my workflow
  4. I don't want to to use openssl or keytool
  5. I don't want to perform key store maintenance

How does on take a well formed PEM encoded certificate on the filesystem and use it directly?


回答1:


I found the answer while trying to do this another way at Set certificate for KeyStore.TrustedCertificateEntry?. Its based on Vit Hnilica's answer at loading a certificate from keystore. I"m going to leave the question with this answer since most Stack Overflow answers start with "convert with openssl, then use keytool ...".

String CA_FILE = ...;

FileInputStream fis = new FileInputStream(CA_FILE);
X509Certificate ca = (X509Certificate) CertificateFactory.getInstance(
        "X.509").generateCertificate(new BufferedInputStream(fis));

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, null);
ks.setCertificateEntry(Integer.toString(1), ca);

TrustManagerFactory tmf = TrustManagerFactory
        .getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
...


来源:https://stackoverflow.com/questions/22493997/use-pem-encoded-ca-cert-on-filesystem-directly-for-https-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!