4 回答

TA貢獻1841條經(jīng)驗 獲得超3個贊
二進制 JKS 文件可能被 Maven 資源插件過濾,導(dǎo)致文件損壞,這是一個很常見的問題:
Maven 在構(gòu)建期間復(fù)制到 Java 資源目錄時損壞 WAV 文件
Maven 在構(gòu)建 jar 時損壞 source/main/resources 中的二進制文件
移動到資源文件夾時生成的證書停止工作
二進制文件基本上被視為文本文件,因此 jar 中的文件以 UTF-8 字符 (?0xEFBFBDEFBFBD
) 而不是 JKS 的幻數(shù) (?0xFEEDFEED
) 開頭。
資源插件文檔包含一個明確的警告:
不要過濾帶有圖像等二進制內(nèi)容的文件!這很可能會導(dǎo)致?lián)p壞的輸出。
可能的解決方案是:
將資源文件夾拆分為一個已過濾的文件夾和一個未過濾的文件夾
全局禁用對擴展名為 .jks 的文件的過濾

TA貢獻1909條經(jīng)驗 獲得超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條經(jīng)驗 獲得超4個贊
二進制文件基本上被視為文本文件,因此 jar 中的文件以 UTF-8 字符 (0xEFBFBDEFBFBD) 開頭,而不是 JKS 的幻數(shù) (0xFEEDFEED)。
我在 pom.xml 文件的屬性部分添加了這兩行
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
它完成了工作

TA貢獻1809條經(jīng)驗 獲得超8個贊
免責(zé)聲明:這還不是一個完整的答案,但我需要一個與 OP 討論的工具。如果這沒有導(dǎo)致解決方案,我將再次刪除答案。
我在這樣的 POJO 中復(fù)制了你的情況:
$ 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
現(xiàn)在在 Maven JAR 模塊中創(chuàng)建一個類似于 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");
}
}
現(xiàn)在構(gòu)建項目并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
所以基本上你的方法應(yīng)該有效。如果沒有,它可以連接到
類加載(但我不這么認(rèn)為,因為密鑰存儲似乎很好),
我在你的調(diào)用堆棧中看到的 AspectJ(或者更確切地說只是 Spring AOP)的東西(也不太可能),
您自己的自定義信任管理器或您的“riskmeter”類所做的任何事情。
請檢查你在你的應(yīng)用程序中使用的完全相同的密鑰庫是否像我的例子一樣從一個簡單的 JAR 中工作,沒有容器或其他花哨的東西。如果是這樣,您就知道問題不是您的密鑰庫。
那么請在這里提供一些反饋。
添加回答
舉報