我正在开发一个使用 SSL 与 MongoDb 进行通信的 Java 应用程序。该应用程序被设计为打包成 .jar 文件,然后在 Docker 容器中运行。 MongoDb 要求您设置 JVM 系统属性才能使 SSL 工作:
System.setProperty("javax.net.ssl.keyStore", pathToJKS);
System.setProperty("javax.net.ssl.keyStorePassword", pw);
我现在的问题是我不知道将 .jks 文件放在哪里并指定正确的路径以便我的应用程序能够在运行时访问它?
目前我的 .jks 文件位于 resources 文件夹 (src/main/resources/store.jks) 中,如果我通过 IDE 执行应用程序,那就没问题,但当然,只要从 .jar 文件执行应用程序,我得到了
java.io.FileNotFoundException
。下面是我当前用来获取路径的代码。
boolean isIDE = ...;
String pathToJKS = isIDE ? "src/main/resources/store.jks" : getPathFromJar("store.jks");
public String getPathFromJar(String filename) {
ClassLoader classLoader = getClass().getClassLoader();
final URL resourceUrl = classLoader.getResource(filename);
if (resourceUrl != null) {
return resourceUrl.toExternalForm();
} else {
return null;
}
}
我的问题是放置 .jks 文件的正确位置在哪里以及如何从 .jar 文件访问它(通过路径)?
所有环境是否使用相同的密钥库?如果是这样,那么我会像您目前所做的那样包括在内。如果没有,则只需将密钥库路径添加为启动中包含的必需参数,例如:
java -jar <jar-file>.jar -Dkeystore.location=/some/location/to/keystore.jks
否则,应执行以下操作以检索位于资源文件夹中的 jar 文件:
//note the slash --v
theResource = MyClass.class.getResource("/store.jks");
// MyClass => class where the getPathFromJar()-method resides
然后只需执行与此类似的操作即可加载它(我想这已经涵盖了,但是嘿):
KeyStore.getInstance(KeyStore.getDefaultType()).load(theResource, password);
在 Created Test Class 文件夹中,子文件夹 src 中包含 keystore.jks 文件。
测试类:
import java.io.*;
public class Test{
public static void main(String... args){
String fileName = args[0];
new Test().readFile(fileName);
}
void readFile(String fileName){
try {
InputStream in = getClass().getResourceAsStream(fileName);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(in, "password".toCharArray());
Enumeration enumeration = keyStore.aliases();
while(enumeration.hasMoreElements()) {
String alias = (String)enumeration.nextElement();
System.out.println("alias name: " + alias);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用以下命令生成 jar:
jar cvfe test.jar Test *.class src/keystore.jks
执行 jar 文件并读取 jar 内的密钥库。
java -jar test.jar /src/keystore.jks
检查后,您只剩下这个选项 - 可以通过 InputStream 从 jar 加载密钥库,并以编程方式显式设置 TrustStore 。
但是,如果它是dockerized的(如op的帖子中所示),那么您可以将
.jks
文件复制到目录并在java中访问它。
在 dockerfile 中
COPY cacerts-plus.jks cacerts-plus.jks
在配置中
activeMQSSLConnectionFactory.setTrustStore(new File("cacerts-plus.jks").toURI().toString());