I'm trying to do something like
URL clientks = com.messaging.SubscriptionManager.class.getResource( "client.ks" );
String path = clientks.toURI().getPath();
System.setProperty( "javax.net.ssl.keyStore", path);
Where client.ks is a file stored in com/messaging in the jar file that I'm running.
The thing that reads the javax.net.ssl.keyStore is expecting a path to the client.ks file which is in the jar. I'd rather not extract the file and put in on the client's machine if possible. So is it possible to reference a file in a jar?
This doesn't work as getPath() returns null. Is there another way to do this?
jks file is located in the resources folder (src/main/resources/store. jks), which is fine if I execute the app via IDE but of course as soon as the app is executed from a . jar file, I am getting a java. io.
What is the Keystore File. The keystore file (. jsk) contains the server's certification, including its private key which is used for cryptographic. The keystore file is protected with a password. Each keystore entry has a unique alias that refers to a particular certificate.
-Djavax. net. ssl. trustStore specifies the truststore file to use to validate client certificates.
Still working on implementation, but I believe it is possible to load the keystore from the jar via InputStream and explicitly set the TrustStore programatically (vs setting the System properties). See the article: Setting multiple truststore on the same JVM
Got it working!
InputStream keystoreInput = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(<path in jar>/client.ks");
InputStream truststoreInput = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(<path in jar>/client.ts");
setSSLFactories(keystoreInput, "password", truststoreInput);
keystoreInput.close();
truststoreInput.close();
private static void setSSLFactories(InputStream keyStream, String keyStorePassword,
InputStream trustStream) throws Exception
{
// Get keyStore
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
// if your store is password protected then declare it (it can be null however)
char[] keyPassword = keyStorePassword.toCharArray();
// load the stream to your store
keyStore.load(keyStream, keyPassword);
// initialize a key manager factory with the key store
KeyManagerFactory keyFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(keyStore, keyPassword);
// get the key managers from the factory
KeyManager[] keyManagers = keyFactory.getKeyManagers();
// Now get trustStore
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
// if your store is password protected then declare it (it can be null however)
//char[] trustPassword = password.toCharArray();
// load the stream to your store
trustStore.load(trustStream, null);
// initialize a trust manager factory with the trusted store
TrustManagerFactory trustFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(trustStore);
// get the trust managers from the factory
TrustManager[] trustManagers = trustFactory.getTrustManagers();
// initialize an ssl context to use these managers and set as default
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(keyManagers, trustManagers, null);
SSLContext.setDefault(sslContext);
}
You can get an InputStream
to a resource in a jar file, but not a File
. If the "thing" that ultimately reads the keystore expects a File
or a path to a file, your only option is to extract it to the filesystem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With