.jarを実行しようとしたときの「無効な署名ファイル」


450

私のJavaプログラムはjarファイルにパッケージ化されており、外部のjarライブラリ、弾む城を利用しています。コードは正常にコンパイルされますが、jarを実行すると次のエラーが発生します。

スレッド「メイン」の例外java.lang.SecurityException:マニフェストメイン属性の無効な署名ファイルダイジェスト

私は1時間以上グーグル検索して説明を探しましたが、ほとんど価値がありませんでした。誰かがこのエラーを以前に見たことがあり、何らかの助けを提供できる場合、私は義務付けられます。


1
あなたは自分の瓶に署名しようとしていますか?もしそうなら、どのように署名しようとしていますか?
Cogsy、2009年

いいえ、少なくとも私はそうは思いません。Xcodeが独自に署名しようとしている可能性がありますが、これをオフにする設定はありません。

実装されたインターフェースを含むjarも署名されているかどうかを確認することを忘れないでください!
gaurav

回答:


47

ここにリストされているソリューションは、ポインタを提供する可能性があります。

マニフェストのメイン属性の無効な署名ファイルダイジェスト

結論:

おそらく公式jarをそのままにして、アプリケーションjarファイルのマニフェストファイルに依存関係として追加するのがおそらく最善です。


3
これをマニフェストファイルにどのように反映しますか?これまで編集したことがありません。私はXcodeを使用していますが、一般的な慣習として、外部jarライブラリをmyproject / libディレクトリに入れてインクルードします。これは私が行っていることです。

@ user123003 ..インテリ-Jの場合のように
MikeM

13
残念ながら、一部の人は「mavenシェードプラグイン」のようなものを使用しているため、元のjarの逐語的コピーを含めることは、そのような場合には簡単ではありません...
rogerdpack

このサイトで回答する恥知らずなプラグイン:stackoverflow.com/a/30922181/448779
foo

maven-assembly-pluginはどうですか?私の場合この問題を解決します
jhenya-d

1083

作成しようとすると、このエラーを得た人のためのユーバージャーとを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>

9
私はこの方法をuber-jarに使用しましたが、うまくいきました。maven.apache.org/plugins/maven-shade-plugin/examples/…に完全なPOMの例があります。これは、含まれているファイルをフィルタリングするこのメソッドを示しています。
M.ダドリー

4
まったく新しいスレッドを開始したくなりましたが、これはGoogleの結果で1位であるため、ここに保持するのが適切であるように思われました。ここにリストされている行は、私が使用しているPOMファイルにあります。アプリケーションを実行すると、まだセキュリティエラーが発生します。正常にビルドされます-もちろん、Uber jarを実行していないときは正常に実行されます-期待どおり。そして、それは確かにオプションですが、別々にしてください-Uber Jarが必要な場合は問題を解決しません。
Gavin Baumanis、2016年

7
これは私にとってはうまくいきますが、なぜ署名ファイルを無視しなければならないのですか?署名のマニフェストが存在する理由は確かです...
ジェリルクック

4
上記を実行した後、必ず「mvn clean」を実行してください!
codeinjuice

4
@JerylCook署名ファイルは、このjarの内容にこれらのファイルがあることを示すためにあります。uber jarを作成すると、jarにさらに多くのファイルが追加されるため、署名が正しくありません。本当に望めば、新しいjarに再署名できますが、もちろん古いjarではなく、あなたの署名が必要です。または、uber jarを配布することはできませんが、代わりに署名されたjarを別のファイルとして含めますが、そもそもuber jarの目的に反します。
LadyCailin

139

Gradleを使用していて、ファットjarを作成して使用しようとしている場合は、次の構文が役立つことがあります。

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

1
これは基本的に、META-INFディレクトリ内の拡張子が.RSA、.SF、または.DSAのすべてのファイルを除外します。
キースP

9
jarファイルに署名すると、これらのファイルがMETA-INFの下に追加されますが、それらが含まれている場合、署名はjarの内容と一致しなくなります。したがって、それらを削除すると、署名の不一致が回避されます。
Peter N. Steinmetz 2014

1
- Gradleの中で脂肪のjarファイルを使用する方法について厳密に似た質問がありstackoverflow.com/questions/4871656/...
トマシュSętkowski

3
これは私にはうまくいきませんでした。私はそのコマンドを持っていたexclude私のfatJar仕事に入れなければなりませんでしたconfigurations.compile.collectstackoverflow.com/a/31426413/103412を
Torsten

1
これもエラーを解決しますError: Could not find or load main class App Caused by: java.lang.ClassNotFoundException: App
vonox7

57

依存関係の一部は、署名されたjarファイルである可能性があります。それらをすべて1つの大きなjarファイルに結合すると、対応する署名ファイルはまだ存在し、「大きな結合」jarファイルと一致しなくなります。そのため、ランタイムはjarファイルが改ざんされたと考えて停止します(これにより...話す)。

jarfileの依存関係から署名ファイルを削除することで問題を解決できます。残念ながら、これをantの1つのステップで行うことはできません

ただし、次のコマンドを使用することで、Antでこれを2つの手順で機能させることができました。各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要素は、将来の変更日付を持つファイルに関するエラーを防ぐことになっています

リンクされたスレッドで見つけた他のバリエーションは私にとってはうまくいきませんでした。


jarを指定する別の方法を使用して、1つのステップで実行できます:<jar destfile = "build / myjar.jar"> <restrict> <not> <name name = "META-INF / *。SF" /> </ not> <archives> <zips> <fileset dir = "jarfolder" contains = " * / .jar" /> </ zips> </ archives> </ restrict> </ jar>
DieterDP

57

次のコマンドを使用してください

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

4
ありがとう、intellij 14でこの問題が発生しましたが、あなたの解決策は私のために機能します!
Mohamad Kouhi Moghadam 2016年

5
ありがとう、Windowsで働いてくれました。7zipでjarを開き、.SFファイルを削除しました。削除する.RSAファイルがありませんでした
candino

3
うわー、私はこのソリューションが素晴らしかったと言うことができますか(そして私は途中で非常に強力な何かを学びました!)これはより多くの投票が必要です。
Dylan_Larkin

@Dylan_Larkinのコメントに同意します。これで解決しました。
フェリペバルデス

26

IntelliJ IDEA 14.01を使用しているときにこの問題が発生しました。

私はそれを修正することができました:

ファイル->プロジェクト構造-> [新規(アーティファクト)の追加]-> jar-> [Jarからモジュールを作成]ウィンドウに依存するモジュールから:

メインクラスを選択してください

ライブラリからのJARファイル出力ディレクトリへのコピーを選択し、マニフェストを介してリンクします


2
依存jarをターゲットjarに入れることはできますか?
coder.chenzhi 2017年

あなたの解決策はうまくいきます!! どうもありがとう!
hzitoun

19

セキュリティはすでに難しいトピックですが、最も一般的な解決策がセキュリティ署名を削除することであることに私は失望しています。JCEにはこれらの署名が必要です。Mavenシェードは、署名をMETA-INFに入れるBouncyCastle jarファイルを爆発させますが、BouncyCastle署名は新しいuber-jar(BC jarに対してのみ)に対して有効ではなく、それがこのスレッドで無効な署名エラーを引き起こしています

はい、@ ruhsuzbaykusによって提案された署名を除外または削除すると、元のエラーは実際に解消されますが、新しい、不可解なエラーが発生する可能性もあります。

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

次のように、アルゴリズムを見つける場所を明示的に指定します。

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

別のエラーが発生しました:

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

この同じスレッドの別の場所にある提案に従って暗号署名を削除したため、JCEはプロバイダーを認証できません

私が見つけた解決策は、jar-in-jarアプローチを使用してBouncyCastle署名を単一の実行可能なjar に保存する実行可能パッカープラグインでした。

更新

これを行う別の方法(正しい方法は?)は、Maven Jar signerを使用することです。これにより、セキュリティエラーが発生することなく、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>

いいえ、JCEに自己署名証明書を認識させる方法はないため、BouncyCastle証明書を保持する必要がある場合は、jar-in-jarプラグインを使用するか、JCE証明書を取得する必要があります。


これは、たとえ作業が集中していても、間違いなく正しい方法です。承認された回答を使用する際の警告について詳しく説明していただきありがとうございます。JCE証明書にSunの署名が必要かどうか知っていますか?または可能
WiteCastle 2017年

1
コード署名証明書を発行できるサードパーティがあります。オプションを表示するには、「Javaコード署名証明書」を検索してください。
MattW '19年

あなた、先生、私の日を作りました!
socona

私を助けました。このライブラリには、私が使用しないいくつかのファイルがあります。そのため、それら以外はfat-jarファイルで役立ちます
Saidolim

14

私は同じ問題に直面しました、どこかを参照した後、それは以下のように機能しました:

<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>

1
これは私の問題を迅速に解決しました!完全を期すために、これはmaven-shade-pluginタグに含めるべきです。
Kuzeko

1
@Kuzekoあなたの提案でanwserを更新しました。ありがとう
m.nguyencntt

8

antを使用してjarファイルを構築する場合、META-INFディレクトリを除外するようにantに指示するだけです。これは私の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>

これらの行をどこに追加すればよいですか?
Addi.Star

4

最近、プロジェクトでIntelliJを使い始めました。ただし、私の同僚の一部は、同じプロジェクトでEclipseをまだ使用しています。今日、IntelliJによって作成されたjarファイルを実行した後も、まったく同じエラーが発生します。ここのすべての解決策はほぼ同じことについて話しているが、それらのどれも私にはうまくいかなかった(おそらく私はANTを使用していないため、mavenビルドが私にhttp://cwiki.apache.org/を参照する他のエラーを与えたconfluence / display / MAVEN / MojoExecutionException、そして私は自分で署名されたjarが何であるかを理解できませんでした!)

最後に、これは私を助けました

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

私のjarファイルから何が削除されたと思いますか?!

deleting: META-INF/ECLIPSE_.SF 
deleting: META-INF/ECLIPSE_.RSA

この問題は一部のEclipse関連のファイルに関連していたようです。


4

gradle太いjarを作成するときにも同じ問題がbuild.gradleあり、exclude行でファイルを更新すると問題が修正されました。

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'
    }
}

1
私は何日もデバッグしていましたが、これは私の脂肪瓶の問題を解決しました。
sysuser

私がデバッグした方法は、ファットjarをjmeter libディレクトリに置くことです。lib / extに問題のあるjarがある場合、この問題は明白ではなく、stackoverflow.com
questions / 37624187 /…の

1
'META-INF / *。RSA'、 'META-INF / *。SF'、 'META-INF / *。DSA'を除外しました。これがありませんでした。依存するjar
ファイル

3

Gradleを使用している場合は、完全なfarJarタスクを次に示します。

version = '1.0'
//create a single Jar with all dependencies
task fatJar(type: Jar) {
    manifest {
        attributes 'Implementation-Title': 'Gradle Jar File Example',  
            'Implementation-Version': version,
            'Main-Class': 'com.example.main'
    }
    baseName = project.name + '-all'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' 
    with jar
}

2

新しいjarのMETA-INFフォルダーを古いjarと比較します(新しいライブラリを追加する前)。新しいファイルが存在する可能性があります。はいの場合、それらを削除できます。それは役立つはずです。よろしく、999michal


2

戦略は、ANTを使用して各Jarファイルからの署名の削除を簡素化することにあります。次の手順に進みます。

  1. 一時ファイルにMANIFEST.MFをコピーする
  2. 一時ファイルから名前SHAエントリを削除する
  3. 一時マニフェストで一時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>

2

エラー:JNIエラーが発生しました。インストールを確認して、再試行してください。スレッド「メイン」の例外java.lang.SecurityException:sun.security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.java: 314)sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.java:268)at java.util.jar.JarVerifier.processEntry(JarVerifier.java:316)at java.util.jar.JarVerifier.update(JarVerifier.java :228)java.util.jar.JarFile.initializeVerifier(JarFile.java:383)at java.util.jar.JarFile.getInputStream(JarFile.java:450)at sun.misc.URLClassPath $ JarLoader $ 2.getInputStream(URLClassPath .java:977)、sun.misc.Resource.cachedInputStream(Resource.java:77)、sun.misc.Resource.getByteBuffer(Resource.java:160)java.net.URLClassLoader.defineClass(URLClassLoader.java:454)at java.net.URLClassLoader.access $ 100(URLClassLoader.java:73)at java.net.URLClassLoader $ 1.run(URLClassLoader.java:368)at java.net.URLClassLoader.findClass(URLClassLoader.java:361)のjava.lang.ClassLoader.loadClassにあるjava.security.AccessController.doPrivileged(Native Method)のjava.net.URLClassLoader $ 1.run(URLClassLoader.java:362) (ClassLoader.java: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)java.net.URLClassLoader.findClass(URLClassLoader.java:361のjava.security.AccessController.doPrivileged(Native Method)のjava.net.URLClassLoader $ 1.run(URLClassLoader.java:362)のrun(URLClassLoader.java:368) )java.lang.ClassLoader.loadClass(ClassLoader.java: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)java.net.URLClassLoader.findClass(URLClassLoader.java:361のjava.security.AccessController.doPrivileged(Native Method)のjava.net.URLClassLoader $ 1.run(URLClassLoader.java:362)のrun(URLClassLoader.java:368) )java.lang.ClassLoader.loadClass(ClassLoader.java: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)331)java.lang.ClassLoader.loadClass(ClassLoader.java:357)at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)331)java.lang.ClassLoader.loadClass(ClassLoader.java:357)at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

私を助けたもの(IntelliJ IDEA 2016.3):ファイル->プロジェクト構造->アーティファクト-> JARの追加->メインクラスの選択->「出力ディレクトリにコピーしてマニフェストでリンク」を選択-> OK->適用->ビルド- >アーティファクトをビルド...->ビルド



1

元のライブラリを解凍したり改ざんしたりせずに、特別なJARクラスローダーを使用してFat JARソリューションを探している場合は、こちらの私のプロジェクトをご覧ください

免責事項:私はコードを記述せず、パッケージ化してMaven Centralで公開し、read-meでその使用方法を説明しました。

私は個人的に、BouncyCastleの依存関係を含む実行可能なuber JARを作成するために使用しています。多分それもあなたのために役立ちます。


0

受け入れられたソリューションに問題がある場合は、DontIncludeResourceTransformerを使用して、シェーディングされたjarからリソースを除外する別の方法があります。

https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html#DontIncludeResourceTransformer

          <transformers>
            <transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
                <resource>BC1024KE.DSA</resource>
            </transformer>
          </transformers>

Shade 3.0以降、このトランスフォーマーはリソースのリストを受け入れます。その前に、それぞれが1つのリソースを持つ複数のトランスフォーマーを使用する必要があります。


0

Intellijが「管理されていないpomファイルが見つかりました」と言ったときに、一番下の行にある[Add as a Maven Project]をクリックすると、Intellijでこれが起こりました。一方、outフォルダーは既に生成されています。そのため、最近の変更はありませんでした。

フォルダを削除してプログラムを実行すると、問題が解決しました。その後、フォルダが再作成されました。

リトルフォックスの答えもご覧ください。私が受け取ったエラーは彼に非常に似ていました。


-1

同様の問題がありました。その理由は、Windowsボックスのデフォルトのものとは異なるJREを使用してJDKを使用してコンパイルしていたためです。

正しいjava.exeを使用して問題を解決しました。


-2

Xamarin.AndroidバインディングプロジェクトのJARファイルを次のようにバインドしようとしたときにこれが発生した場合:

JARTOXML:警告J2XA006:com.your.classの反映中にクラスが見つからないというエラーが発生しました:マニフェストのメイン属性の無効な署名ファイルダイジェスト

Winzipを使用してJARファイルを開き、meta-infディレクトリを削除するだけです。再構築-完了したジョブ


1
これは恐ろしいテクニックです。絶対に恐ろしい。ローカルで修正を加えても、入ってくるjarは変更されません
sinisterrook
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.