4 回答
TA贡献1841条经验 获得超3个赞
二进制 JKS 文件可能被 Maven 资源插件过滤,导致文件损坏,这是一个很常见的问题:
Maven 在构建期间复制到 Java 资源目录时损坏 WAV 文件
Maven 在构建 jar 时损坏 source/main/resources 中的二进制文件
移动到资源文件夹时生成的证书停止工作
二进制文件基本上被视为文本文件,因此 jar 中的文件以 UTF-8 字符 ( 0xEFBFBDEFBFBD
) 而不是 JKS 的幻数 ( 0xFEEDFEED
) 开头。
资源插件文档包含一个明确的警告:
不要过滤带有图像等二进制内容的文件!这很可能会导致损坏的输出。
可能的解决方案是:
将资源文件夹拆分为一个已过滤的文件夹和一个未过滤的文件夹
全局禁用对扩展名为 .jks 的文件的过滤
TA贡献1909条经验 获得超7个赞
确保避免过滤您的密钥库文件 jks
喜欢
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/*.jks</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*.jks</include>
</includes>
</resource>
</resources>
TA贡献1811条经验 获得超4个赞
二进制文件基本上被视为文本文件,因此 jar 中的文件以 UTF-8 字符 (0xEFBFBDEFBFBD) 开头,而不是 JKS 的幻数 (0xFEEDFEED)。
我在 pom.xml 文件的属性部分添加了这两行
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
它完成了工作
TA贡献1809条经验 获得超8个赞
免责声明:这还不是一个完整的答案,但我需要一个与 OP 讨论的工具。如果这没有导致解决方案,我将再次删除答案。
我在这样的 POJO 中复制了你的情况:
$ openssl req -new -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out MyCertificate.crt -keyout MyKey.key
(answer all questions with RETURN = accept defaults)
$ keytool -v -import -alias devserver -file MyCertificate.crt -keystore src/main/resources/cacerts.jks -storetype JKS
Enter keystore password: testtest
Re-enter new password: testtest
(...)
Trust this certificate? [no]: yes
Certificate was added to keystore
[Storing src/main/resources/cacerts.jks]
$ keytool -list -keystore src/main/resources/cacerts.jks
Enter keystore password: testtest
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
devserver, 24.08.2019, trustedCertEntry,
Certificate fingerprint (SHA-256): A2:E1:49:FB:9C:26:6B:8A:21:45:A4:AA:F4:86:A0:A7:82:B8:08:BE:75:A6:BF:E8:F5:13:9E:31:23:8E:B0:71
现在在 Maven JAR 模块中创建一个类似于 OP 所示代码的类:
package de.scrum_master.stackoverflow;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
public class CustomTrustManager {
public static void main(String[] args) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
InputStream stream;
stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("cacerts.jks");
System.out.println(stream);
if (stream == null) {
stream = CustomTrustManager.class.getClassLoader().getResourceAsStream("cacerts.jks");
}
if(stream == null) {
System.out.println("Unable to load cacerts.jks. This is needed to make HTTPS connections to internal servers.");
throw new RuntimeException("Keystore not found");
}
KeyStore myTrustStore = KeyStore.getInstance("JKS");
myTrustStore.load(stream, "testtest".toCharArray());
System.out.println("Keystore loaded");
}
}
现在构建项目并mvn clean package运行它:
$ java -cp target/my-sample-1.0-SNAPSHOT.jar de.scrum_master.stackoverflow.CustomTrustManager
sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@3d4eac69
Keystore loaded
所以基本上你的方法应该有效。如果没有,它可以连接到
类加载(但我不这么认为,因为密钥存储似乎很好),
我在你的调用堆栈中看到的 AspectJ(或者更确切地说只是 Spring AOP)的东西(也不太可能),
您自己的自定义信任管理器或您的“riskmeter”类所做的任何事情。
请检查你在你的应用程序中使用的完全相同的密钥库是否像我的例子一样从一个简单的 JAR 中工作,没有容器或其他花哨的东西。如果是这样,您就知道问题不是您的密钥库。
那么请在这里提供一些反馈。
添加回答
举报