I have been given the following key/cert from a service team to call their API over SSL, which I verfied thru curl command.
1. QA.test.key
2. QA.test.pem
CURL command:
curl --key QA.test.key --cert ./QA.test.pem -X POST --header "Content-Type: application/json" --header "Accept: application/json" -d '{"pan":"1234567890123456", "client": " Application Name "}' https://test-qa.abc.com/tokenize
Now, to call the API in Java over https, do I need to do the following?
- Create a self signed jks file
- import the .key and .pem to new test.jks file?
Do the following
public class TestApp {
final static String KEYSTORE_PASSWORD = "testing";
static
{
System.setProperty("javax.net.ssl.trustStore", "src/main/resources/test.jks");
System.setProperty("javax.net.ssl.trustStorePassword", KEYSTORE_PASSWORD);
System.setProperty("javax.net.ssl.keyStore", "src/main/resources/test.jks");
System.setProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD);
}
public static void main(String[] args) {
SpringApplication.run(TestApp.class, args);
}
}
I am getting Invalid Certificate error while using the jks file, what would be the best way to create a jks file and import .key and .pem file for it to work properly?
Create a PKCS #12 file using OpenSSL utilities. Then you can specify this as your key store using the system properties.
openssl pkcs12 -export -in QA.test.pem -inkey QA.test.key -out test.pkcs12
This command will prompt for a password to encrypt the new PKCS #12 file. It may also prompt for the password that was used to encrypt QA.test.key
, if any.
javax.net.ssl.keyStore=test.pkcs12
javax.net.ssl.keyStorePassword=<whatever you entered when creating PKCS #12>
javax.net.ssl.keyStoreType=PKCS12
The trustStore
properties are separate; they affect how to authenticate the server. If the server uses a certificate issued by a "real" CA, the necessary certificates should be present in the Java runtime already. Otherwise, you'll have to create an additional key store, which can be done using Java's keytool
command.
Note that Java 9 will use PKCS #12 files as the default keystore type.
The simplest way to create a jks is using the GUI tool portecle
http://portecle.sourceforge.net
Create JKS> import key/pair
You can also use keytool and OpenSSL. Check this importing an existing x509 certificate and private key in Java keystore to use in ssl
Consider you need a keyStore for the client certificate and a trustStore for the certificates of your server. Usually the client certificate also contains them. If not, include also the certificates in the JKS (same file u other)
To invoke and send json you can use httpsURLconnection
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslFactory);
conn.setMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type","application/json");
conn.connect();
OutputStream os = conn.getOutputStream();
os.write(jsonString.getBytes());
os.flush();
os.close();
To create a socketFactory you could use
SSLContext sc = SSLContext.getDefault();
SSLSocketFactory sslFactory = sc.getSocketFactory();
Here you have a full example (creating truststore and keystore with java code) How can I use different certificates on specific connections?
If you have problems with the SSL connection add
System.setProperty("javax.net.debug", "ssl");