"Fichier de signature non valide" lors d'une tentative d'exécution a.jar

mon programme java est empaqueté dans un fichier jar et utilise une bibliothèque jar externe, bouncy castle . Mon code se compile bien, mais exécuter le jar conduit à l'erreur suivante:

Exception dans le thread" main " java.lang.SecurityException: signature non Valide digest de fichier pour Manifester les attributs principaux

j'ai cherché sur Google pendant plus d'une heure une explication et j'ai trouvé très peu de valeur. Si quelqu'un a déjà vu cette erreur et peut offrir de l'aide, je vous en serais reconnaissant.

376
demandé sur Gray 2009-06-16 07:49:51

17 réponses

la solution listée ici pourrait fournir un indicateur.

signature non Valide digest de fichier pour Manifester les attributs principaux

en bref:

il est probablement préférable de garder le bocal officiel comme est et juste l'ajouter comme une dépendance dans le fichier manifeste pour votre l'application fichier jar.

42
répondu Nrj 2013-06-03 21:51:10

pour ceux qui ont eu cette erreur en essayant de créer un uber-jar avec maven-shade-plugin , la solution est d'exclure les fichiers de signature manifestes 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>
934
répondu ruhsuzbaykus 2017-05-23 11:33:26

pour ceux qui utilisent gradle et essayent de créer et d'utiliser un pot de graisse, 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' 
}
114
répondu Keith P 2013-01-21 15:15:29

certaines de vos dépendances sont probablement des jarfiles signés. Lorsque vous les combinez tous en un seul grand fichier jarfile, les fichiers de signature correspondants sont toujours présents, et ne correspondent plus au fichier jarfile "big combined", de sorte que l'exécution s'arrête en pensant que le fichier jar a été altéré (ce qui est le cas...a façon de 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 faire cela en un seul étape dans ant .

cependant, J'ai pu obtenir ce fonctionnement avec Ant en deux étapes, sans nommer spécifiquement 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é prévenir les erreurs sur les fichiers avec des dates de modification dans le futur .

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

53
répondu Rich Apodaca 2017-05-23 12:26:42

veuillez utiliser la commande suivante

zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'
38
répondu Peter2711 2017-02-15 09:52:18

j'ai eu ce problème en utilisant IntelliJ idée 14.01.

j'ai été en mesure de le réparer par:

fichier - > Structure du projet - > ajouter de nouveaux (artefacts)->jar - >à partir de Modules avec des dépendances sur la création de Jar à partir de la fenêtre du Module:

Sélectionnez votre classe principale

fichier JAR des bibliothèques Sélectionnez Copier dans le répertoire de sortie et le lien via le manifeste

22
répondu Travis 2014-12-11 18:07:46

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

Oui, l'exclusion ou la suppression des signatures suggérées par @ruhsuzbaykus fait effectivement disparaître l'erreur originale, mais elle peut aussi conduire à 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 parce que nous avons supprimé les signatures cryptographiques en suivant la suggestion ailleurs dans ce même fil .

la solution que j'ai trouvée était le exécutable packer plugin qui utilise une approche jar-in-jar à préserver la signature de BouncyCastle dans un seul, JAR exécutable.

mise à JOUR :

une autre façon de le faire (la bonne façon? est d'utiliser le Maven Pot signataire . Cela vous permet de continuer à utiliser Maven shade sans obtenir des erreurs de sécurité. Cependant, vous devez avoir un certificat de signature de code (Oracle suggère de rechercher "Java Code Signing Certificate"). La configuration de 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 d'amener JCE à reconnaître un cert auto-signé, donc si vous avez besoin de préserver les certs de BouncyCastle, vous devez soit utiliser le plugin jar-in-jar ou obtenir un cert JCE.

9
répondu MattW 2017-09-05 22:16:47

en supposant que vous construisez votre fichier jar avec ant, vous pouvez juste lui demander de laisser de côté le méta-INF dir. C'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
répondu Kim Stebel 2010-09-05 07:02:07

comparez le dossier META-INF dans new jar avec l'ancien jar (avant d'ajouter de nouvelles bibliothèques). Il est possible qu'il y aura de nouveaux fichiers. Si oui, vous pouvez les supprimer. Il devrait en aide. Égard, 999michal

2
répondu 999michal 2010-06-02 14:12:59

erreur: une erreur JNI s'est produite, veuillez vérifier votre installation et essayer à nouveau Exception in thread "main" java.lang.SecurityException: non valide au coucher du soleil.sécurité.util.SignatureFileVerifier.processImpl (SignatureFileVerifier.java: 314) au coucher du soleil.sécurité.util.SignatureFileVerifier.processus (SignatureFileVerifier.java: 268) à java.util.pot.JarVerifier.processEntry (JarVerifier.java: 316) à Java.util.pot.JarVerifier.mise à jour(JarVerifier.java: 228) à java.util.pot.Jarfiles.initializeVerifier (JarFile.java: 383) à java.util.jar.Jarfiles.gettinputstream (JarFile.java: 450) au coucher du soleil.misc.URLClassPath$JarLoader $ 2.getInputStream (URLClassPath.java: 977) au coucher du soleil.misc.Ressources.cachedInputStream (ressource.java: 77) au coucher du soleil.misc.Ressources.getByteBuffer (ressource.java: 160) à java.net.URLClassLoader.defineClass (URLClassLoader.java: 454) à java.net.URLClassLoader.accéder à $ 100 (URLClassLoader.java: 73) à java.net.URLClassLoader$1.run (URLClassLoader.java: 368) à java.net.URLClassLoader$1.run (URLClassLoader.java: 362) à java.sécurité.AccessController.doPrivileged(Native method) à java.net.URLClassLoader.findClass (URLClassLoader.java: 361) à java.lang.Chargeur de classe.loadClass (ClassLoader.java: 424) au coucher du soleil.misc.Lanceur $ AppClassLoader.loadClass (lanceur.java: 331) à Java.lang.Chargeur de classe.loadClass (ClassLoader.java: 357) au coucher du soleil.lanceur.LauncherHelper.checkAndLoadMain(LauncherHelper.java: 495)

ce qui m'a aidé (idée IntelliJ 2016.3): Fichier - > Structure du projet - > artéfacts - > ajouter JAR - > choisir la classe principale -> choisir "Copier dans le répertoire de sortie et le lien via le manifeste" - > OK -> Appliquer -> construire - > construire artéfacts... - >Construire 151920920"

2
répondu Little Fox 2017-02-11 09:16:14

j'ai eu un problème similaire. La raison en était que je compilais en utilisant un JDK avec un JRE différent de celui par défaut dans ma fenêtre Windows.

en utilisant le java correct.exe a résolu mon problème.

1
répondu Jus12 2010-08-02 12:54:36

il est possible que deux signataires différents saccagent java mind.

essayer de supprimer le dossier META-INF de jar, en ajoutant manifeste et signer JAR à nouveau, il m'a aidé: http://jehy.ru/articles/2013/12/13/invalid-signature-file-digest-for-manifest-main-attributes /

1
répondu Jehy 2013-12-13 07:09:20

une stratégie consisterait à utiliser ANT pour simplifier la suppression de la signature de chaque fichier Jar. Elle procéderait comme suit:

  1. copie du Manifeste.MF dans un fichier temporaire
  2. suppression du nom et SHA entrées du fichier temporaire
  3. la Création d'un temporaire fichier Jar avec le temporaire manifeste
  4. suppression le manifeste temporaire
  5. changement de l'origine des fichiers Jar avec le temporaire

voici un ANT macrodef faire 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 alors être appelée ainsi dans une tâche ANT:

<target name="unsignJar">
    <unsignjar jarFile="org.test.myjartounsign.jar" />
</target>
1
répondu bdulac 2016-12-26 15:32:33

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. Alors que toutes les solutions ici parlent de presque la même chose, aucune d'entre elles n'a fonctionné pour moi facilement (probablement parce que je n'utilise pas ANT, Maven build m'a donné d'autres erreurs qui m'ont référé à http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException , et aussi je ne pouvais pas comprendre ce que sont les pots signés par moi-même!)

enfin, ce 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 la question était pertinente pour certains fichiers relatifs à eclipse.

1
répondu mhn_namak 2018-06-09 04:50:22

si vous obtenez ceci en essayant de lier des fichiers JAR pour un Xamarin.

JARTOXML : avertissement J2XA006: catégorie manquante erreur tout en reflétant com.votre.classe: dossier de signature non valide pour les attributs principaux du Manifeste

il suffit d'ouvrir les fichiers JAR en utilisant Winzip et de supprimer les répertoires meta-inf. Reconstruire-travail fait

0
répondu Dean Wild 2014-09-23 09:30:06

dans le cas où vous utilisez gradle, voici une tâche farJar complète:

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
}
0
répondu Nick De Greek 2018-05-11 14:27:37

si vous êtes à la recherche d'une solution Fat JAR sans déballer ou altérer les bibliothèques d'origine, mais avec un classloader JAR spécial, jetez un oeil à mon projet ici .

avertissement: je n'ai pas écrit le code, juste l'empaqueter et le publier sur Maven Central et de décrire dans mon read-me Comment l'utiliser.

Je l'utilise personnellement pour créer des pots Uber exécutables qui contiennent des dépendances de BouncyCastle. Peut-être que c'est utile pour vous, trop.

0
répondu kriegaex 2018-08-04 11:43:02