web-dev-qa-db-fra.com

"Fichier de signature non valide" lors de la tentative d'exécution d'un fichier .jar

Mon programme Java est empaqueté dans un fichier jar et utilise une bibliothèque de jar externe, château gonflable . Mon code se compile bien, mais l’exécution du fichier jar conduit à l’erreur suivante:

Exception dans le fil "principal" Java.lang.SecurityException: Résumé du fichier de signature non valide pour les attributs principaux Manifest

Cela fait plus d'une heure que je recherche des explications sur Google et trouve très peu de valeur. Si quelqu'un avait déjà vu cette erreur et pouvait offrir de l'aide, j'en serais obligé.

424
user123003

La solution répertoriée ici peut fournir un pointeur.

Résumé du fichier de signature non valide pour les attributs principaux du manifeste

Ligne de fond:

Il est probablement préférable de conserver le fichier jar officiel en l'état et de simplement l'ajouter en tant que dépendance dans le fichier manifeste du fichier jar de votre application.

46
Nrj

Pour ceux qui ont eu cette erreur en essayant de créer un ber-jar avec maven-shade-plugin, la solution consiste à exclure les fichiers de signature de manifeste en ajoutant les lignes suivantes à la configuration du 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>
1020
ruhsuzbaykus

Pour ceux qui utilisent gradle et qui tentent de créer et d’utiliser un gros pot, la syntaxe suivante pourrait aider.

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

Certaines de vos dépendances sont probablement des fichiers jar signés. Lorsque vous les combinez tous dans un seul grand fichier jar, les fichiers de signature correspondants sont toujours présents et ne correspondent plus au "grand fichier jar", de sorte que le moteur d'exécution s'interrompt en pensant que le fichier jar a été altéré (... parler).

Vous pouvez résoudre le problème en éliminant les fichiers de signature de vos dépendances jarfile. Malheureusement, il n’est pas possible de le faire en une seule étape .

Cependant, j'ai pu utiliser Ant en deux étapes, sans nommer chaque dépendance jarfile, en utilisant:

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

L'élément sleep est censé empêcher erreurs concernant les fichiers avec des dates de modification ultérieures .

Les autres variations que j'ai trouvées dans les threads liés ne fonctionnaient pas pour moi.

55
Rich Apodaca

Veuillez utiliser la commande suivante

Zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'
49
Peter2711

J'ai eu ce problème lors de l'utilisation d'IntelliJ IDEA 14.01.

J'ai pu le réparer en:

Fichier-> Structure du projet-> Ajouter des nouveaux artefacts -> jar-> à partir de modules avec dépendances dans la fenêtre Créer un jar à partir d'un module:

Sélectionnez votre classe principale

Fichier JAR à partir de bibliothèques Sélectionnez une copie dans le répertoire de sortie et un lien via manifeste

25
Travis

La sécurité est déjà un sujet difficile, mais je suis déçu de voir que la solution la plus populaire consiste à supprimer les signatures de sécurité. JCE requiert ces signatures . La couleur Maven explose le fichier de pots BouncyCastle qui place les signatures dans META-INF, mais les signatures de BouncyCastle ne sont pas valables pour un nouveau, uber-jar (uniquement pour le pot BC), et c'est ce qui cause l'erreur de signature invalide dans ce fil .

Oui, le fait d'exclure ou de supprimer les signatures suggérées par @ruhsuzbaykus élimine effectivement l'erreur d'origine, mais elle peut également entraîner de nouvelles erreurs cryptiques:

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

En spécifiant explicitement où trouver l'algorithme comme ceci:

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

J'ai pu obtenir une erreur différente:

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

JCE ne peut pas authentifier le fournisseur car nous avons supprimé les signatures cryptographiques en suivant la suggestion ailleurs dans ce même fil .

La solution que j’ai trouvée est le plugin programme d’exécution exécutable qui utilise une approche jar-in-jar pour conserver la signature BouncyCastle dans un jarre unique, exécutable.

UPDATE:

Une autre façon de faire cela (la bonne?) Consiste à utiliser signataire Maven Jar . Cela vous permet de continuer à utiliser l'ombre Maven sans commettre d'erreur de sécurité. CEPENDANT, vous devez disposer d'un certificat de signature de code (Oracle suggère de rechercher le "certificat de signature de code Java"). La configuration POM ressemble à ceci:

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

Non, il n'y a aucun moyen de faire en sorte que JCE reconnaisse un certificat auto-signé. Par conséquent, si vous devez préserver les certificats BouncyCastle, vous devez utiliser le plug-in jar-in-jar ou obtenir un certificat JCE.

13
MattW

En supposant que vous construisiez votre fichier jar avec ant, vous pouvez simplement lui demander de laisser le répertoire META-INF. Ceci est une version simplifiée de ma cible 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>
8
Kim Stebel

J'ai fait face au même problème, après référence quelque part, cela a fonctionné de la manière suivante:

<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>
5
m.nguyencntt

J'ai récemment commencé à utiliser IntelliJ sur mes projets. Cependant, certains de mes collègues utilisent encore Eclipse sur les mêmes projets. Aujourd'hui, j'ai la même erreur après avoir exécuté le fichier jar créé par mon IntelliJ. Bien que toutes les solutions ici parlent presque de la même chose, aucune d’entre elles ne fonctionnait facilement pour moi (probablement parce que je n’utilise pas ANT, maven build m’a donné d’autres erreurs qui me renvoyaient à http: // cwiki. Apache.org/confluence/display/MAVEN/MojoExecutionException , et aussi je ne pouvais pas comprendre ce que sont les bocaux signés par moi-même!)

Enfin, this m'a aidé

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

Devinez ce qui a été supprimé de mon fichier jar?!

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

Il semble que le problème concerne certains fichiers relatifs à Eclipse.

4
mhn_namak

Si vous utilisez Gradle, voici une tâche complète de 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
Nick De Greek

Comparez le dossier META-INF dans le nouveau pot avec le vieux (avant d'ajouter de nouvelles bibliothèques). Il est possible qu'il y ait de nouveaux fichiers. Si oui, vous pouvez les supprimer. Cela devrait aider. Cordialement, 999ichal

2
999michal

Erreur: une erreur JNI s'est produite. Vérifiez votre installation et réessayez. Exception dans le thread "principal" Java.lang.SecurityException: Résumé du fichier de signature non valide pour les attributs principaux Manifest sur Sun.security.util.SignatureFileVerifier.processImpl (SignatureFileVerifier.Java: 314) à Sun.security.util.SignatureFileVerifier.process (SignatureFileVerifier.Java:268) à Java.util.jar.JarVerifier.processEntry (JarVerifier.Java:316) à Java.util.jar.JarVerifier.update (JarVerifier.Java : 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) sur Sun.misc.Resource.cachedInputStream (Resource.Java:77) sur Sun.misc.Resource.getByteBuffer (Resource.Java:160) sur Java.net.URLClassLoader.defineClass (URLClassLoader.Java:45) sur Java.net.URLClassLoader.access 100 $ (URLClassLoader.Java:73) sur Java.net.URLClassLoader $ 1.run (URLClassLoader.Java:368) sur Java.net.URLClassLoade r $ 1.run (URLClassLoader.Java:362) à Java.security.AccessController.doPrivileged (Méthode native) à Java.net.URLClassLoader.findClass (URLClassLoader.Java:361) à Java.lang.ClassLoader.loadClass (ClassLoader.Java : 424) à Sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.Java:331) à Java.lang.ClassLoader.loadClass (ClassLoader.Java:357) à Sun.launcher.LauncherHelper.checkAndLoadMain (LauncherHelper.Java:5)

Ce qui m'a aidé (IntelliJ IDEA 2016.3): Fichier -> Structure du projet -> Artefacts -> Ajouter un fichier JAR -> Sélectionner la classe principale -> Choisir "copier dans le répertoire de sortie et créer un lien via manifeste" -> OK - > Appliquer -> Construire -> Construire des artefacts ... -> Construire

2
Little Fox

Une stratégie consisterait à utiliser ANT pour simplifier la suppression de la signature de chaque fichier Jar. Il procéderait avec les étapes suivantes:

  1. Copier MANIFEST.MF dans un fichier temporaire
  2. Suppression des entrées Name et SHA du fichier temporaire
  3. Création d'un fichier Jar temporaire avec le manifeste temporaire
  4. Retrait du manifeste temporaire
  5. Échange du fichier Jar d'origine avec le fichier temporaire

Voici un ANT macrodef faisant le travail:

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

`

La définition peut ensuite être appelée de cette manière dans une tâche ANT:

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

Il est possible que deux signataires différents fouillent l'esprit Java.

Essayez de supprimer le dossier META-INF de jar, d’ajouter un manifeste et de signer à nouveau JAR, cela m’a aidé: http://jehy.ru/articles/2013/12/13/invalid-signature-file-digest-for- manifest-main-attributs /

1
Jehy

Si vous recherchez une solution Fat JAR sans décompresser ni altérer les bibliothèques d'origine, mais avec un chargeur de classe JAR spécial, jetez un œil à mon projet ici .

Clause de non-responsabilité: je n'ai pas écrit le code, je l'ai juste empaqueté, publié dans Maven Central et décrit dans mon read-me comment l'utiliser.

Personnellement, je l'utilise pour créer des fichiers JAR exécutables contenant des dépendances BouncyCastle. Peut-être que cela vous est utile aussi.

1
kriegaex

Le même problème se produisait dans gradle lors de la création d'un fichier Jar fat. La mise à jour du fichier build.gradle avec une ligne d'exclusion corrigeait le problème.

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'
    }
}
0
Ahmad Al-Kurdi