跳至主要内容

Java 整合

sslTrus 提供 sslTrusJarsigner Java Provider,可與 JDK 內建的 jarsigner 工具搭配使用,透過遠端程式碼簽署服務完成 Java JAR 檔案簽署。

簽署過程中,程式碼簽署私鑰始終保存在雲端 HSM 中。本機負責產生待簽署資料與簽署結構,並透過 sslTrusJarsigner Provider 呼叫遠端服務完成私鑰簽署。

除 JAR 簽署外,sslTrusJarsigner 亦提供 XMLDSig 簽署能力,可用於 XML 數位簽章場景。

準備工作​

使用前請準備:

  • JDK 8 或更高版本。
  • sslTrusJarsigner-<version>.jar。
  • Access Key。
  • Access Secret。
  • 憑證編號(Cert Code)。
  • 待簽署的 JAR 檔案或 XML 檔案。

本文範例中的 <version>、存取憑證、憑證編號及檔案路徑均需替換為實際值。

下載 sslTrusJarsigner​

從 sslTrusJarsigner 發佈頁 下載最新發佈套件並解壓縮。

發佈套件包含:

sslTrusJarsigner-<version>.jar
SHA-256 校验文件

建議在使用前根據 SHA-256 校驗檔案驗證 sslTrusJarsigner-<version>.jar 的完整性。

檢查執行環境​

首先確認 Java 和 JDK 內建的 jarsigner 可以正常使用:

java -version
jarsigner -help

檢查 sslTrusJarsigner 版本:

java -jar sslTrusJarsigner-<version>.jar --version

查看說明:

java -jar sslTrusJarsigner-<version>.jar --help

如果 jarsigner 命令不存在,請確認目前安裝的是完整 JDK,而不是僅包含 Java Runtime 的執行環境。

配置存取憑證​

sslTrusJarsigner 透過環境變數讀取遠端程式碼簽署服務的存取憑證與憑證編號。

Linux 和 macOS​

export SSLTRUS_JARSIGNER_ACCESS_KEY="YOUR_ACCESS_KEY"
export SSLTRUS_JARSIGNER_ACCESS_SECRET="YOUR_ACCESS_SECRET"
export SSLTRUS_JARSIGNER_CERT_CODE="YOUR_CERT_CODE"

Windows PowerShell​

$env:SSLTRUS_JARSIGNER_ACCESS_KEY = "YOUR_ACCESS_KEY"
$env:SSLTRUS_JARSIGNER_ACCESS_SECRET = "YOUR_ACCESS_SECRET"
$env:SSLTRUS_JARSIGNER_CERT_CODE = "YOUR_CERT_CODE"

如果服務人員提供了專用服務地址,還需要設定 SSLTRUS_JARSIGNER_URL。

Linux 和 macOS:

export SSLTRUS_JARSIGNER_URL="YOUR_SERVICE_URL"

Windows PowerShell:

$env:SSLTRUS_JARSIGNER_URL = "YOUR_SERVICE_URL"

如果沒有提供專用服務地址,不需要設定該變數。

Access Secret 屬於敏感憑證,不應寫入原始碼、公開設定檔或建置日誌。自動化環境建議透過 CI/CD Secret 或其他憑證管理機制注入。

JAR 簽署​

sslTrusJarsigner 透過 Java Security Provider 機制與標準 jarsigner 工具整合。

下面的範例將:

app-unsigned.jar

簽名後輸出為:

app-signed.jar

JDK 9 或更高版本​

Linux 和 macOS:

jarsigner \
-keystore NONE \
-storetype SSLTRUS \
-storepass SSLTRUS \
-providerPath "sslTrusJarsigner-<version>.jar" \
-providerClass com.racent.codesign.SSLTrusProvider \
-sigalg SHA256withRSA \
-tsa http://timestamp.sectigo.com \
-signedjar "app-signed.jar" \
"app-unsigned.jar" \
"$SSLTRUS_JARSIGNER_CERT_CODE"

Windows PowerShell:

jarsigner `
-keystore NONE `
-storetype SSLTRUS `
-storepass SSLTRUS `
-providerPath "sslTrusJarsigner-<version>.jar" `
-providerClass com.racent.codesign.SSLTrusProvider `
-sigalg SHA256withRSA `
-tsa http://timestamp.sectigo.com `
-signedjar "app-signed.jar" `
"app-unsigned.jar" `
"$env:SSLTRUS_JARSIGNER_CERT_CODE"

JDK 8​

JDK 8 載入 Provider 的方式與 JDK 9 及更高版本不同。

首先確認:

JAVA_HOME

指向完整的 JDK 8 安裝目錄。

Linux 和 macOS:

jarsigner \
-J-cp \
-J"$JAVA_HOME/lib/tools.jar:sslTrusJarsigner-<version>.jar" \
-keystore NONE \
-storetype SSLTRUS \
-storepass SSLTRUS \
-providerClass com.racent.codesign.SSLTrusProvider \
-sigalg SHA256withRSA \
-tsa http://timestamp.sectigo.com \
-signedjar "app-signed.jar" \
"app-unsigned.jar" \
"$SSLTRUS_JARSIGNER_CERT_CODE"

Windows PowerShell:

jarsigner `
-J-cp `
"-J$env:JAVA_HOME\lib\tools.jar;sslTrusJarsigner-<version>.jar" `
-keystore NONE `
-storetype SSLTRUS `
-storepass SSLTRUS `
-providerClass com.racent.codesign.SSLTrusProvider `
-sigalg SHA256withRSA `
-tsa http://timestamp.sectigo.com `
-signedjar "app-signed.jar" `
"app-unsigned.jar" `
"$env:SSLTRUS_JARSIGNER_CERT_CODE"

使用時需要注意:

  • 命令最後的證書編號必須與 SSLTRUS_JARSIGNER_CERT_CODE 一致。
  • 建議使用 -signedjar 輸出至新檔案,避免覆寫原始 JAR。
  • 範例使用 SHA256withRSA 完成程式碼簽名。
  • 不需要時間戳記時,可以刪除 -tsa 及其後的時間戳記位址。

時間戳記​

建議為正式發佈的 JAR 簽名加入可信任的時間戳記。

示例中使用:

http://timestamp.sectigo.com

對應參數:

-tsa http://timestamp.sectigo.com

時間戳用於證明簽名發生的時間,不會將原始 JAR 檔案上傳到時間戳伺服器。

如果需要使用其他時間戳服務,可以將 -tsa 後的地址替換為符合實際簽名策略的 TSA 地址。

關於不同時間戳服務及生產環境選擇,請參閱 參考資料。

XML 簽名​

sslTrusJarsigner 還提供 XML 數位簽章能力。

XML 檔案可以透過 sign-xml 命令產生 XMLDSig Enveloped Signature。

簽名過程中,本地負責產生 XMLDSig 所需的摘要和簽名結構,實際 RSA 私鑰簽名由遠端程式碼簽章服務完成。

Linux 和 macOS​

java -jar sslTrusJarsigner-<version>.jar \
sign-xml \
"input.xml" \
"signed.xml" \
"$SSLTRUS_JARSIGNER_CERT_CODE"

Windows PowerShell​

java -jar sslTrusJarsigner-<version>.jar `
sign-xml `
"input.xml" `
"signed.xml" `
"$env:SSLTRUS_JARSIGNER_CERT_CODE"

預設輸出的 KeyInfo 僅包含葉端證書。如果接收方要求 XML 內含完整證書鏈,可以在命令末尾加入 --full-chain 參數。

执行完成后:

input.xml

為原始 XML 檔案,

signed.xml

為包含 XML 數位簽章的輸出檔案。

程式碼簽章私密金鑰不會寫入 XML 檔案,也不會儲存到本機電腦。

產生驗證檔案​

簽章完成後,可以產生用於驗證簽章的 JKS 檔案。

Linux 和 macOS:

java -jar sslTrusJarsigner-<version>.jar \
generate-keystore \
"$SSLTRUS_JARSIGNER_CERT_CODE" \
"verify.jks" \
"SSLTRUS"

Windows PowerShell:

java -jar sslTrusJarsigner-<version>.jar `
generate-keystore `
"$env:SSLTRUS_JARSIGNER_CERT_CODE" `
"verify.jks" `
"SSLTRUS"

生成:

verify.jks

該檔案僅用於簽章驗證,不能用於執行程式碼簽章。

程式碼簽章私密金鑰仍保存在遠端 HSM 中,不會寫入 verify.jks。

驗證 JAR 簽章​

使用產生的 verify.jks 驗證簽章:

jarsigner \
-verify \
-verbose \
-certs \
-keystore "verify.jks" \
-storetype JKS \
-storepass "SSLTRUS" \
"app-signed.jar"

如果只需要查看 JAR 中已有的簽名資訊,可以執行:

jarsigner -verify -verbose -certs "app-signed.jar"

驗證簽章只會檢查現有簽章,不會重新呼叫遠端私密金鑰執行簽章。

簽章次數​

Jarsigner 的簽章次數按照實際成功完成的遠端簽章動作計算。

通常情況下:

操作簽章次數
對一個 JAR 成功簽章一次1 次
分別簽章 3 個 JAR3 次
對同一個 JAR 再執行一次簽章再增加 1 次
jarsigner -verify 驗證簽章0 次
產生 verify.jks0 次

因此,簽章次數主要取決於實際執行了多少次成功的簽章操作,而不是 Java 專案的原始程式碼檔案數量。

詳細規則請參閱 參考資料。

常見問題​

缺少 Access Key、Access Secret 或憑證編號​

確認目前終端已經設定:

SSLTRUS_JARSIGNER_ACCESS_KEY
SSLTRUS_JARSIGNER_ACCESS_SECRET
SSLTRUS_JARSIGNER_CERT_CODE

設定環境變數後,需要在同一個終端工作階段中執行簽署命令。

Invalid option: -providerPath​

如果出現:

Invalid option: -providerPath

通常表示目前使用的是 JDK 8。

JDK 8 不使用 JDK 9 及更高版本範例中的 -providerPath 參數,請改用本文提供的 JDK 8 命令。

無法載入 SSLTrusProvider​

如果提示無法載入:

com.racent.codesign.SSLTrusProvider

請檢查:

  • sslTrusJarsigner-<version>.jar 路徑是否正確。
  • 檔案名稱中的版本號是否與實際檔案一致。
  • JDK 8 環境中的 JAVA_HOME 是否指向完整 JDK。

找不到證書或 alias​

請檢查:

  • 證書編號是否正確。
  • 命令最後指定的證書編號是否與 SSLTRUS_JARSIGNER_CERT_CODE 一致。
  • 當前 Access Key 和 Access Secret 是否具有該證書的使用權限。

遠端簽名請求失敗​

請檢查:

  • 當前網路是否能夠訪問遠端程式碼簽章服務。
  • 代理、防火牆和 DNS 設定是否正常。
  • Access Key 和 Access Secret 是否正確。
  • 證書編號是否正確。
  • 如果使用專用服務地址,SSLTRUS_JARSIGNER_URL 是否按照實際交付資訊設定。

排查問題時可以保留完整錯誤資訊,但在提交日誌或錯誤截圖前,應刪除或去識別化 Access Secret 等敏感憑證。

時間戳失敗​

確認當前網路能夠訪問 -tsa 指定的時間戳伺服器。

如果業務允許,可以暫時移除:

-tsa <URL>

再次執行簽署,用於判斷問題發生在遠端程式碼簽署還是時間戳記請求階段。

安全說明​

Java 整合過程中需要注意:

  • Access Secret 應作為敏感憑證保存。
  • 不要將存取憑證提交到 Git 倉庫。
  • 不要在日誌中輸出完整 Access Secret。
  • verify.jks 僅用於驗證,不包含可用於遠端簽署的私密金鑰。
  • 本地 sslTrusJarsigner Provider 不保存程式碼簽署私密金鑰。
  • 私密金鑰簽署操作始終由遠端程式碼簽署服務完成。
  • 自動化環境建議使用 CI/CD Secret 或專用憑證管理系統注入存取憑證。

相關整合方式​

如果需要簽署的不是 Java JAR 或 XML 檔案,可以根據實際情境選擇其他整合方式:

情境整合方式
直接透過命令列簽署 EXE、DLL、MSI 等檔案用戶端工具
Microsoft SignTool、Visual Studio 等 Windows 工具Windows Provider
GitHub Actions、Electron Builder 等自動化建置CI/CD 與建置工具
自行開發遠端簽署用戶端API 整合