Install4J 10.0.9用后置处理器+Jsign签名时遇'Unsupported file'错误
环境与背景
- 构建环境:Linux Jenkins服务器、Install4J 10.0.9(计划升级至11)、DigiCert ONE smctl工具、Jsign 6.0.0
- 核心需求:代码签名证书存储在HSM安全设备中,用smctl+Jsign完成Install4J生成的Windows媒体文件及内部可执行文件签名
- 当前操作:禁用Install4J内置的Windows媒体签名功能,在Install4J的
Media/windows-32/Executable processing里配置后置处理器,开启"为每个可执行文件运行命令",执行签名命令:/opt/codesigning/smtools-linux-x64/smctl sign --keypair-alias ${compiler:codeSigningKeypairAlias} --config-file ${compiler:codeSigningPkcs11Config} --input $OUTFILE --verbose
问题现象
执行签名时Jsign报错Unsupported file,关键日志如下:
signCommand command for file /tmp/install4j5073564965492722622_dir/set1/signed11460690974641472065.exe FAILED Compiling launcher 'application-update-diagnosis': using icon file ./icon.ico Creating GUI mode application. Running post-processor Post-processor command is "/opt/codesigning/smtools-linux-x64/smctl" "sign" "--keypair-alias" "OUR_KEYPAIR_ALIAS" "--config-file" "/opt/codesigning/pkcs11properties.cfg" "--input" "/tmp/install4j5073564965492722622_dir/set1/signed4735947293422229253.exe" "--verbose" Command : jsign -keystore "/opt/codesigning/pkcs11properties.cfg" -storepass NONE -storetype PKCS11 -alg SHA-256 -tsaurl http://timestamp.digicert.com -alias OUR_KEYPAIR_ALIAS "/tmp/install4j5073564965492722622_dir/set1/signed4735947293422229253.exe" Error : exit status 1: Picked up JAVA_TOOL_OPTIONS: -Dmaven.ext.class.path="/home/jenkins/workspace/IPL-17095_fix_unsigned_exe_files@tmp/withMavend45d2b78/pipeline-maven-spy.jar" -Dorg.jenkinsci.plugins.pipeline.maven.reportsFolder="/home/jenkins/workspace/IPL-17095_fix_unsigned_exe_files@tmp/withMavend45d2b78" jsign: Unsupported file: /tmp/install4j5073564965492722622_dir/set1/signed4735947293422229253.exe Try `jsign --help' for more information. signCommand command for file /tmp/install4j5073564965492722622_dir/set1/signed4735947293422229253.exe FAILED
解决方法
先检查文件本身
用Linux的file命令验证目标exe是不是标准PE格式:file /tmp/xxx.exe,正常应该输出PE32 executable之类的内容。如果文件损坏或者不是标准PE文件,Jsign就会报不支持。另外也可能是Install4J还没写完文件就触发了签名,试试在命令前加个短暂延迟,比如sleep 2 && /opt/codesigning/...,等文件完全生成再签。强制指定文件类型
Jsign自动检测文件类型可能对Install4J生成的特殊启动器失效,在smctl命令里加--type pe参数强制指定为PE格式,修改后的命令:/opt/codesigning/smtools-linux-x64/smctl sign --keypair-alias ${compiler:codeSigningKeypairAlias} --config-file ${compiler:codeSigningPkcs11Config} --input $OUTFILE --verbose --type pe升级Jsign版本
Jsign 6.0.0对某些PE文件的兼容性不够,试试升级到最新稳定版(比如7.x系列),新版本通常会修复更多文件识别的问题。换Install4J的签名配置方式
不用后置处理器,改成Install4J的"External tool"签名配置:在General Settings > Code Signing里选"External tool",把smctl命令配成签名工具,这样Install4J会在合适的时机调用签名,确保文件已经完全生成。排查HSM相关问题
虽然报错是文件不支持,但也可能是HSM连接有问题导致Jsign返回了误导性错误。先确认pkcs11properties.cfg配置正确,Jenkins用户有访问HSM设备的权限,再直接用Jsign命令签一个已知有效的PE文件,看看HSM能不能正常工作。
内容的提问来源于stack exchange,提问作者Thomas

