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 个 JAR | 3 次 |
| 对同一个 JAR 再执行一次签名 | 再增加 1 次 |
jarsigner -verify 验证签名 | 0 次 |
生成 verify.jks | 0 次 |
因此,签名次数主要取决于实际执行了多少次成功的签名操作,而不是 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仅用于验证,不包含可用于远程签名的私钥。- 本地
sslTrusJarsignerProvider 不保存代码签名私钥。 - 私钥签名操作始终由远程代码签名服务完成。
- 自动化环境建议使用 CI/CD Secret 或专用凭证管理系统注入访问凭证。
相关集成方式
如果需要签名的不是 Java JAR 或 XML 文件,可以根据实际场景选择其他集成方式:
| 场景 | 集成方式 |
|---|---|
| 直接通过命令行签名 EXE、DLL、MSI 等文件 | 客户端工具 |
| Microsoft SignTool、Visual Studio 等 Windows 工具 | Windows Provider |
| GitHub Actions、Electron Builder 等自动化构建 | CI/CD 与构建工具 |
| 自行开发远程签名客户端 | API 集成 |