"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.
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.
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>
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'
}
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.
veuillez utiliser la commande suivante
zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'
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
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.
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>
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
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"
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.
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 /
une stratégie consisterait à utiliser ANT pour simplifier la suppression de la signature de chaque fichier Jar. Elle procéderait comme suit:
- copie du Manifeste.MF dans un fichier temporaire
- suppression du nom et SHA entrées du fichier temporaire
- la Création d'un temporaire fichier Jar avec le temporaire manifeste
- suppression le manifeste temporaire
- 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>
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.
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
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
}
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.