Java打包JAR报Invalid signature file digest及BouncyCastle认证问题求助
JavaFX打包BouncyCastle报错解决方案
核心问题原因
- 打包时将BouncyCastle(以下简称BC)的签名Jar和业务代码合并为一个Fat Jar时,BC原有的官方签名和新增的未签名代码、其他依赖Jar的签名冲突,导致JVM校验签名失败,触发初始的签名摘要不匹配异常
- 直接删除BC的签名文件会导致JCE无法认证BC提供方,JCE规则要求加密服务提供方的Jar必须持有Oracle颁发的JCE专属签名,否则无法作为系统级加密提供方被调用
- 自行用普通个人证书签名BC无效,普通证书不在JCE信任列表内,签名后的BC依然无法通过校验
可行解决方案(按操作复杂度从低到高排序)
方案1:不合并BC到Fat Jar中(最推荐,无需改代码)
打包时不要把BC的Jar和业务代码打包成同一个文件,发布时将业务Jar、BC Jar以及其他依赖Jar放在同一个目录下,启动时用java -cp ./* 你的主类全限定名命令启动即可。
如果使用IntelliJ构建制品,直接在制品配置中选择「将依赖复制到单独目录」而非「解压到输出Jar」,从根源避免合并签名冲突。
方案2:代码层面动态注册BC,绕开JCE签名校验
不需要修改打包逻辑,只需要在调用BC相关加密方法前,执行一次动态注册代码,即可绕开系统级签名校验,无需将BC配置到JRE安全文件中:
import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.security.Security; // 应用启动时或调用加解密逻辑前执行一次即可 Security.insertProviderAt(new BouncyCastleProvider(), 1);
该方案下可以正常删除合并Jar中META-INF目录下所有后缀为.SF、.DSA、.RSA的文件,解决初始的签名冲突问题,不会再触发BC认证异常。
方案3:使用Maven打包插件自动处理签名冲突
如果使用Maven构建项目,配置maven-shade-plugin时增加过滤规则,排除其他依赖的签名文件,仅保留BC的官方签名文件即可:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> <!-- 单独保留BouncyCastle的官方签名文件 --> <filter> <artifact>org.bouncycastle:*</artifact> <includes> <include>META-INF/*.SF</include> <include>META-INF/*.DSA</include> <include>META-INF/*.RSA</include> </includes> </filter> </filters> </configuration> </execution> </executions> </plugin>
错误操作说明
- 不要用个人生成的普通证书签名BC,普通证书未经过Oracle JCE认证,签名后的BC依然不被JCE认可
- 不要在合并BC和业务代码后再对整包签名,合并后的Jar中存在你自己的未签名业务资源(比如css、fxml等文件),会导致BC签名校验失败
内容的提问来源于stack exchange,提问作者Anthony
相关产品推荐
相关产品推荐

