尝试运行.jar时出现“签名文件无效”

我的Java程序打包在一个jar文件中,并使用外部jar库, 充气城堡 。 我的代码编译好,但运行该jar导致以下错误:

线程“main”中的exceptionjava.lang.SecurityException:Manifest主要属性的签名文件摘要无效

我search了一个多小时寻找解释,发现价值很小。 如果有人曾经看到这个错误,并可以提供一些帮助,我会被迫。

这里列出的解决scheme可以提供一个指针。

Manifest主要属性的签名文件摘要无效

底线:

这可能是最好的官方jar保持原样,只是添加它作为您的应用程序jar文件清单文件的依赖项。

对于那些在使用maven-shade-plugin创build一个uber-jar的时候出现这个错误的解决办法是通过在插件configuration中join以下几行来排除清单签名文件:

 <configuration> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> <!-- Additional configuration. --> </configuration> 

对于那些使用gradle并试图创build和使用fat jar的人来说,下面的语法可能会有所帮助。

 jar { doFirst { from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } } exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' } 

你的一些依赖可能是签名的jar文件。 当你把它们全部合并成一个大的jar文件时,相应的签名文件仍然存在,并且不再与“大合并”jar文件相匹配,所以运行时暂停,认为jar文件被篡改了说话)。

您可以通过从jarfile依赖关系中消除签名文件来解决问题。 不幸的是, 在ant中不可能一步到位 。

但是,我能够通过两步来使用Ant来处理这个问题,而不用专门命名每个jarfile依赖关系,方法是使用:

 <target name="jar" depends="compile" description="Create one big jarfile."> <jar jarfile="${output.dir}/deps.jar"> <zipgroupfileset dir="jars"> <include name="**/*.jar" /> </zipgroupfileset> </jar> <sleep seconds="1" /> <jar jarfile="${output.dir}/myjar.jar" basedir="${classes.dir}"> <zipfileset src="${output.dir}/deps.jar" excludes="META-INF/*.SF" /> <manifest> <attribute name="Main-Class" value="com.mycompany.MyMain" /> </manifest> </jar> </target> 

sleep元素应该能够防止将来修改date的文件错误 。

我在链接线程中发现的其他变体对我不起作用。

请使用下面的命令

 zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF' 

使用IntelliJ IDEA 14.01时遇到了这个问题。

我能够通过以下方式解决它:

文件 – >项目结构 – >添加新(工件) – > jar->从模块创build从模块JAR窗口依赖的模块:

select你主要的课程

来自库的JAR文件select复制到输出目录并通过清单链接

假设你用antbuild立你的jar文件,你可以指示ant忽略META-INF目录。 这是我的ant目标的简化版本:

 <jar destfile="app.jar" basedir="${classes.dir}"> <zipfileset excludes="META-INF/**/*" src="${lib.dir}/bcprov-jdk16-145.jar"></zipfileset> <manifest> <attribute name="Main-Class" value="app.Main"/> </manifest> </jar> 

将新jar中的文件夹META-INF与旧jar进行比较(添加新库之前)。 有可能会有新的文件。 如果是的话,你可以删除它们。 它应该有所帮助。 关心,999michal

安全已经是一个艰难的话题,但我很失望看到最stream行的解决scheme是删除安全签名。 JCE需要这些签名 。 Maven遮罩爆炸BouncyCastle jar文件,将签名放入META-INF,但BouncyCastle签名对于新的超级jar(仅用于BC jar) 无效,这就是导致此线程中的无效签名错误的原因

是的,排除或删除@ruhsuzbaykusbuild议的签名的确会使原始错误消失,但是也会导致新的,神秘的错误:

 java.security.NoSuchAlgorithmException: PBEWithSHA256And256BitAES-CBC-BC SecretKeyFactory not available 

通过明确指定在哪里find这样的algorithm:

 SecretKeyFactory.getInstance("PBEWithSHA256And256BitAES-CBC-BC","BC"); 

我能够得到一个不同的错误:

 java.security.NoSuchProviderException: JCE cannot authenticate the provider BC 

JCE无法validation提供程序,因为我们已经 通过在此同一线程的其他地方按照build议 删除了encryption签名

我find的解决scheme是可执行的打包程序插件,它使用jar-in-jar方法将BouncyCastle签名保存在单个可执行的jar文件中。

更新

另一种方法(正确的方法)是使用Maven Jar签名者 。 这使您可以继续使用Maven遮罩而不会出现安全错误。 但是,您必须拥有代码签名证书(Oraclebuild议您search“Java代码签名证书”)。 POMconfiguration如下所示:

 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <filters> <filter> <artifact>org.bouncycastle:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>your.class.here</mainClass> </transformer> </transformers> <shadedArtifactAttached>true</shadedArtifactAttached> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jarsigner-plugin</artifactId> <version>1.4</version> <executions> <execution> <id>sign</id> <goals> <goal>sign</goal> </goals> </execution> <execution> <id>verify</id> <goals> <goal>verify</goal> </goals> </execution> </executions> <configuration> <keystore>/path/to/myKeystore</keystore> <alias>myfirstkey</alias> <storepass>111111</storepass> <keypass>111111</keypass> </configuration> </plugin> 

不,无法让JCE识别自签名证书,所以如果您需要保留BouncyCastle证书,则必须使用jar-in-jar插件或获得JCE证书。

我有一个类似的问题。 原因是我使用的JDK使用的是不同于我的Windows中的默认JRE的JDK。

使用正确的java.exe解决了我的问题。

有可能是两个不同的签名者弄糟了java的头脑。

尝试从jar中删除META-INF文件夹,添加清单和再次签名JAR,它帮助我: http : //jehy.ru/articles/2013/12/13/invalid-signature-file-digest-for-manifest-main-属性/

一个策略是使用ANT来简化从每个Jar文件中删除签名。 它将按照以下步骤进行:

  1. 在临时文件中复制MANIFEST.MF
  2. 从临时文件中删除名称SHA条目
  3. 使用临时清单创build临时Jar文件
  4. 删除临时清单
  5. 使用临时文件交换原始Jar文件

这是一个ANT macrodef做的工作:

 <macrodef name="unsignjar" description="To unsign a specific Jar file"> <attribute name="jarfile" description="The jar file to unsign" /> <sequential> <!-- Copying to the temporary manifest file --> <copy toFile="@{jarFile}_MANIFEST.tmp"> <resources> <zipentry zipfile="@{jarFile}" name="META-INF/MANIFEST.MF"/> </resources> </copy> <!-- Removing the Name and SHA entries from the temporary file --> <replaceregexp file="@{jarFile}_MANIFEST.tmp" match="\nName:(.+?)\nSH" replace="SH" flags="gis" byline="false"/> <replaceregexp file="@{jarFile}_MANIFEST.tmp" match="SHA(.*)" replace="" flags="gis" byline="false"/> <!-- Creating a temporary Jar file with the temporary manifest --> <jar jarfile="@{jarFile}.tmp" manifest="@{jarFile}_MANIFEST.tmp"> <zipfileset src="@{jarFile}"> <include name="**"/> <exclude name="META-INF/*.SF"/> <exclude name="META-INF/*.DSA"/> <exclude name="META-INF/*.RSA"/> </zipfileset> </jar> <!-- Removing the temporary manifest --> <delete file="@{jarFile}_MANIFEST.tmp" /> <!-- Swapping the original Jar file with the temporary one --> <move file="@{jarFile}.tmp" tofile="@{jarFile}" overwrite="true" /> </sequential> 

`

这个定义在ANT任务中可以这样调用:

 <target name="unsignJar"> <unsignjar jarFile="org.test.myjartounsign.jar" /> </target> 

错误:发生了JNI错误,请检查您的安装,然后再次尝试线程“main”中的exceptionjava.lang.SecurityException:在sun.security.util.SignatureFileVerifier.processImpl上清除主要属性的签名文件摘要无效(SignatureFileVerifier.java:在java.util.jar.JarVerifier.processEntry(JarVerifier.java:316)上的java.util.jar.JarVerifier.update(JarVerifier.java)上的sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.java:268) :228)在java.util.jar.JarFile.initializeVerifier(JarFile.java:383)在java.util.jar.JarFile.getInputStream(JarFile.java:450)在sun.misc.URLClassPath $ JarLoader $ 2.getInputStream(URLClassPath .java:977)at sun.misc.Resource.cachedInputStream(Resource.java:77)at sun.misc.Resource.getByteBuffer(Resource.java:160)at java.net.URLClassLoader.defineClass(URLClassLoader.java:454) java.net.URLClassLoader.access $ 100(URLClassLoader.java:73)在java.net.URLClassLoader $ 1.run(URLClassLoader.java:368)at java.net.URLClassLoade 在java.net.URLClassLoader.findClass(URLClassLoader.java:361)处,java.lang.ClassLoader.loadClass(ClassLoader.java)返回java.security.AccessController.doPrivileged(Native方法)的r $ 1.run(URLClassLoader.java:362) :424)at sun.misc.Launcher $ AppClassLoader.loadClass(Launcher.java:331)at java.lang.ClassLoader.loadClass(ClassLoader.java:357)at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

(IntelliJ IDEA 2016.3):文件 – >项目结构 – >工件 – >添加JAR – >select主类 – >select“复制到输出目录并通过清单链接” – >确定 – >应用 – >生成 – >构build工件… – >构build

如果您在尝试为Xamarin.Android绑定项目绑定JAR文件时遇到此问题,请执行以下操作:

JARTOXML:警告J2XA006:在反映com.your.class时引发缺less的类错误:Manifest主要属性的签名文件摘要无效

只需使用Winzip打开JAR文件并删除meta-inf目录即可。 重build – 完成任务