尝试运行.jar时"无效的签名文件"

434 java jar executable-jar

我的java程序打包在一个jar文件中,并使用外部jar库,bouncy castle.我的代码编译得很好,但是运行jar会导致以下错误:

线程"main"中的异常java.lang.SecurityException:Manifest主要属性的签名文件摘要无效

我用谷歌搜索了一个多小时寻找解释,发现很少有价值.如果有人以前看过这个错误并且可以提供一些帮助,我将不得不承担责任.

ruh*_*kus 1040

对于那些谁得到了试图创建一个当这个错误尤伯杯罐子maven-shade-plugin,解决的办法是通过添加以下行插件配置排除清单签名文件:

<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>
Run Code Online (Sandbox Code Playgroud)

  • 我把这种方法用于我的超级罐,效果很好.http://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html上有一个完整的POM示例,它显示了此方法筛选包含的文件. (7认同)
  • 这对我有用,但是...为什么我们必须忽略签名文件?我确定签名清单是有原因的.... (7认同)
  • 我很想开始一个全新的线程 - 但由于这是Googles结果中的第一名 - 似乎很容易将它保留在这里.这里列出的行在我正在使用的POM文件中 - 我在运行应用程序时仍然遇到安全性错误.它建立得很好 - 当然没有做优步罐时运行正常 - 正如预期的那样.虽然这当然是一个选择 - 让它们分开 - 如果你想要一个Uber Jar,它并不能解决问题. (3认同)
  • 做完上面之后一定要做"mvn clean"! (3认同)
  • @JerylCook签名文件用于指示此jar的内容包含这些文件.当你制作一个超级jar时,你会向jar中添加更多的文件,因此签名不正确.如果你真的想要,你可以重新签名新罐子,但当然这将是你的签名,而不是旧签名.或者,你不能分发超级jar,而是将签名的jar包含为一个单独的文件,但是那时首先会破坏超级jar的目的. (3认同)

Kei*_*h P 135

对于那些使用gradle并尝试创建和使用fat jar的人,以下语法可能会有所帮助.

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

  • 签署jar文件会在META-INF下添加这些文件,但是当它们被包含时,签名不再与jar内容一致.因此,删除它们可以避免签名不匹配. (9认同)
  • 这不适合我.我不得不将`exclude`放到我的`fatJar`任务中,该任务具有`configurations.compile.collect`命令.请参见http://stackoverflow.com/a/31426413/103412 (2认同)
  • 这也解决了错误“错误:无法找到或加载主类应用程序引起:java.lang.ClassNotFoundException:应用程序” (2认同)

Ric*_*aca 55

您的一些依赖项可能是已签名的jar文件.当你将它们全部组合成一个大的jar文件时,相应的签名文件仍然存在,并且不再匹配"大组合"jar文件,因此运行时停止认为jar文件已经被篡改(它... ...说话).

您可以通过从jarfile依赖项中删除签名文件来解决此问题.不幸的是,蚂蚁不可能一步到位.

但是,我能够通过两个步骤使用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>
Run Code Online (Sandbox Code Playgroud)

sleep元素应该可以防止将来修改日期的文件出错.

我在链接线程中找到的其他变体对我不起作用.


Pet*_*711 51

请使用以下命令

zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你,在Windows工作.刚用7zip打开jar,删除了.SF文件.我没有要删除的.RSA文件 (5认同)
  • 谢谢,我有intellij 14的这个问题,你的解决方案适合我! (4认同)
  • 哇,我能说这个解决方案很棒吗(我在这个过程中学到了非常强大的功能!)这需要更多的支持. (3认同)

Nrj*_*Nrj 46

此处列出的解决方案可能提供指针.

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

底线:

最好保留官方jar,只需将其作为依赖项添加到应用程序jar文件的清单文件中.

  • 不幸的是,我们中的一些人使用"maven shade plugin"这样的东西,因此在这些情况下包括原始jar的逐字副本并不那么容易...... (12认同)
  • 我如何在清单文件中反映这一点?我以前从未编辑过.我正在使用Xcode,常见的惯例是将外部jar库放在myproject/lib目录中以供包含,这就是我正在做的事情. (3认同)
  • 在清单文件中尝试Class-Path:LIB_PACKAGE /. (2认同)

Tra*_*vis 25

使用IntelliJ IDEA 14.01时出现此问题.

我能够解决它:

文件 - >项目结构 - >添加新(工件) - > jar->从模块窗口创建Jar的具有依赖性的模块:

选择你的主要课程

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

  • 是否可以将依赖罐放入目标罐中? (2认同)

Mat*_*ttW 15

安全性已经是一个棘手的话题,但我很失望地看到最流行的解决方案是删除安全签名.JCE需要这些签名.Maven树荫爆炸了BouncyCastle jar文件,它将签名放入META-INF,但是BouncyCastle签名对于新的超级jar(仅适用于BC jar)无效,这就是导致此线程中出现无效签名错误的原因.

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

java.security.NoSuchAlgorithmException: PBEWithSHA256And256BitAES-CBC-BC SecretKeyFactory not available
Run Code Online (Sandbox Code Playgroud)

通过明确指定在哪里找到算法,如下所示:

SecretKeyFactory.getInstance("PBEWithSHA256And256BitAES-CBC-BC","BC");
Run Code Online (Sandbox Code Playgroud)

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

java.security.NoSuchProviderException: JCE cannot authenticate the provider BC
Run Code Online (Sandbox Code Playgroud)

JCE无法对提供程序进行身份验证,因为我们已 按照同一线程中的其他位置删除了加密签名.

我找到的解决方案是可执行的打包程序插件,它使用jar-in-jar方法在单个可执行jar中保留BouncyCastle签名.

更新:

另一种方法(正确的方法?)是使用Maven Jar签名者.这使您可以继续使用Maven阴影而不会出现安全错误.但是,您必须拥有代码签名证书(Oracle建议搜索"Java代码签名证书").POM配置如下所示:

<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>
Run Code Online (Sandbox Code Playgroud)

不,没有办法让JCE识别自签名证书,因此如果您需要保留BouncyCastle证书,则必须使用jar-in-jar插件或获得JCE证书.


Kim*_*bel 8

假设你使用ant构建jar文件,你可以指示ant省略META-INF目录.这是我的蚂蚁目标的简化版本:

<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>
Run Code Online (Sandbox Code Playgroud)


Ahm*_*rdi 6

gradle我在创建一个胖罐子时遇到了同样的问题;build.gradle使用排除行更新文件更正了该问题。

jar {
    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
    manifest {
        attributes 'Main-Class': 'com.test.Main'
    }
}
Run Code Online (Sandbox Code Playgroud)


m.n*_*ntt 6

在引用某处后,我遇到了同样的问题,它的工作方式如下所示:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.1</version>
    <configuration>
        <createDependencyReducedPom>false</createDependencyReducedPom>
    </configuration>
    <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>
                </filters>
            </configuration>
        </execution>
    </executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)


mhn*_*mak 5

我最近开始在我的项目中使用 IntelliJ。但是,我的一些同事仍然在相同的项目中使用 Eclipse。今天,在执行由我的 IntelliJ 创建的 jar 文件后,我遇到了同样的错误。虽然这里的所有解决方案都在谈论几乎相同的事情,但没有一个对我来说很容易(可能是因为我不使用 ANT,maven build 给了我其他错误,这些错误将我推荐给了http://cwiki.apache.org/ confluence/display/MAVEN/MojoExecutionException,而且我自己也无法弄清楚签名的罐子是什么!)

最后,对我有帮助

zip -d demoSampler.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'
Run Code Online (Sandbox Code Playgroud)

猜猜从我的 jar 文件中删除了什么?!

deleting: META-INF/ECLIPSE_.SF 
deleting: META-INF/ECLIPSE_.RSA
Run Code Online (Sandbox Code Playgroud)

该问题似乎与某些与 eclipse 相关的文件有关。