跳至主要内容

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 整合