java - how - "Archivo de firma no válido" al intentar ejecutar un.jar
how to make jar file in java (17)
Mi programa java está empaquetado en un archivo jar y utiliza una biblioteca de archivos jar externa, bouncy castle . Mi código compila bien, pero al ejecutar el jar se produce el siguiente error:
Excepción en el hilo "main" java.lang.SecurityException: resumen de archivo de firma no válido para los atributos principales del manifiesto
He buscado en Google durante más de una hora buscando una explicación y he encontrado muy poco de valor. Si alguien ha visto este error antes y podría ofrecer alguna ayuda, estaría agradecido.
Error: se ha producido un error de JNI, verifique su instalación e intente nuevamente. Excepción en el hilo "main" java.lang.SecurityException: Resumen de archivo de firma no válido para los atributos principales del manifiesto en sun.security.util.SignatureFileVerifier.processImpl (SignatureFileVerifier.java: 314) en sun.security.util.SignatureFileVerifier.process (SignatureFileVerifier.java:268) en java.util.jar.JarVerifier.processEntry (JarVerifier.java:316) en java.util.jar.JarVerifier.update (JarVerifier.java : 228) en java.util.jar.JarFile.initializeVerifier (JarFile.java:383) en java.util.jar.JarFile.getInputStream (JarFile.java:450) en sun.misc.URLClassPath $ JarLoader $ 2.getInputStream (URLClassPath) .java: 977) en sun.misc.Resource.cachedInputStream (Resource.java:77) en sun.misc.Resource.getByteBuffer (Resource.java:160) en java.net.URLClassLoader.defineClass (URLClassLoader.java:454) en java.net.URLClassLoader.access $ 100 (URLClassLoader.java:73) en java.net.URLClassLoader $ 1.run (URLClassLoader.java:368) en java.net.URLClassLoade r $ 1.run (URLClassLoader.java:362) en java.security.AccessController.doPrivileged (Método nativo) en java.net.URLClassLoader.findClass (URLClassLoader.java:361) en java.lang.ClassLoader.loadClass (ClassLoader.java) : 424) en sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.java:331) en java.lang.ClassLoader.loadClass (ClassLoader.java:357) en sun.launcher.LauncherHelper.checkAndLoadMain (LauncherHelper.4004)
Lo que me ayudó (IntelliJ IDEA 2016.3): Archivo -> Estructura del proyecto -> Artefactos -> Agregar JAR -> Seleccionar clase principal -> Elegir "copiar al directorio de salida y vincular mediante el manifiesto" -> Aceptar -> Aplicar -> Crear - > Construir artefactos ... -> Construir
Algunas de sus dependencias son probablemente jarfiles firmados. Cuando se combinan todos en un archivo jar grande, los archivos de firmas correspondientes aún están presentes y ya no coinciden con el archivo jar "combinado grande", por lo que el tiempo de ejecución se detiene pensando que el archivo jar ha sido manipulado (lo que ... hablar).
Puede resolver el problema eliminando los archivos de firmas de las dependencias de su archivo jar. Desafortunadamente, no es posible hacer esto en un solo paso en ant .
Sin embargo, pude conseguir que esto funcionara con Ant en dos pasos, sin nombrar específicamente cada dependencia de jarfile, usando:
<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>
Se supone que el elemento de suspensión evita errores en los archivos con fechas de modificación en el futuro .
Otras variaciones que encontré en los hilos enlazados no funcionaron para mí.
Compare la carpeta META-INF en el nuevo contenedor con el anterior (antes de agregar nuevas bibliotecas). Es posible que haya nuevos archivos. Si es así, puedes eliminarlos. Debería ayudar. Saludos, 999michal
En caso de que estés usando gradle, aquí hay una tarea completa de farJar:
zip -d demoSampler.jar ''META-INF/*.SF'' ''META-INF/*.RSA'' ''META-INF/*SF''
Es posible que dos firmantes diferentes arruinen la mente de Java.
Intente eliminar la carpeta META-INF del tarro, agregar manifiesto y firmar JAR nuevamente, me ayudó: http://jehy.ru/articles/2013/12/13/invalid-signature-file-digest-for-manifest-main-attributes/
La seguridad ya es un tema difícil, pero me decepciona ver que la solución más popular es eliminar las firmas de seguridad. JCE requiere estas firmas . La sombra de Maven explota el archivo jar BouncyCastle que coloca las firmas en META-INF, pero las firmas BouncyCastle no son válidas para un nuevo uber-jar (solo para el tarro BC), y eso es lo que causa el error de firma no válida en este hilo .
Sí, excluir o eliminar las firmas como lo sugiere @ruhsuzbaykus hace que el error original desaparezca, pero también puede dar lugar a nuevos errores crípticos:
java.security.NoSuchAlgorithmException: PBEWithSHA256And256BitAES-CBC-BC SecretKeyFactory not available
Al especificar explícitamente dónde encontrar el algoritmo de esta manera:
SecretKeyFactory.getInstance("PBEWithSHA256And256BitAES-CBC-BC","BC");
Pude obtener un error diferente:
java.security.NoSuchProviderException: JCE cannot authenticate the provider BC
JCE no puede autenticar al proveedor porque hemos eliminado las firmas criptográficas siguiendo la sugerencia en otra parte de este mismo hilo .
La solución que encontré fue el complemento de empaquetador ejecutable que utiliza un enfoque de jar-in-jar para conservar la firma BouncyCastle en un solo jar ejecutable.
ACTUALIZACIÓN :
Otra forma de hacer esto (¿la forma correcta?) Es usar el firmante de Maven Jar . Esto le permite seguir usando la cortina de Maven sin obtener errores de seguridad. SIN EMBARGO, debe tener un certificado de firma de código (Oracle sugiere buscar "Certificado de firma de código Java"). La configuración de POM se ve así:
<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>
No, no hay forma de que JCE reconozca un certificado autofirmado, por lo que si necesita conservar los certificados BouncyCastle, debe usar el plugin jar-in-jar o obtener un certificado JCE.
La solución enumerada aquí podría proporcionar un puntero.
Resumen de archivo de firma no válido para los atributos principales de Manifest
Línea de fondo :
Probablemente sea mejor mantener el archivo jar oficial tal como está y simplemente agregarlo como una dependencia en el archivo de manifiesto para su archivo jar de la aplicación.
Para aquellos que usan gradle e intentan crear y usar un tarro gordo, la siguiente sintaxis puede ayudar.
jar {
doFirst {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
exclude ''META-INF/*.RSA'', ''META-INF/*.SF'',''META-INF/*.DSA''
}
Por favor use el siguiente comando
zip -d yourjar.jar ''META-INF/*.SF'' ''META-INF/*.RSA'' ''META-INF/*SF''
Recientemente comencé a usar IntelliJ en mis proyectos. Sin embargo, algunos de mis colegas todavía usan Eclipse en los mismos proyectos. Hoy, recibí el mismo error después de ejecutar el archivo jar creado por mi IntelliJ. Si bien todas las soluciones aquí hablan de casi lo mismo, ninguna de ellas funcionó para mí fácilmente (posiblemente porque no uso ANT, Maven Build me dio otros errores que me remitieron a http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException , y tampoco pude averiguar cuáles son los frascos firmados por mí mismo.)
Finalmente, esto me ayudó.
deleting: META-INF/ECLIPSE_.SF
deleting: META-INF/ECLIPSE_.RSA
¿Adivina qué se ha eliminado de mi archivo jar?
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
}
Parece que el problema era relevante para algunos archivos relevantes para eclipse.
Si está buscando una solución Fat JAR sin descomprimir o manipular las bibliotecas originales pero con un cargador de clases JAR especial, eche un vistazo a mi proyecto aquí .
Descargo de responsabilidad: no escribí el código, solo lo empaqueté, lo publiqué en Maven Central y describí en mi léame cómo usarlo.
Personalmente lo uso para crear JARs uber ejecutables que contienen dependencias BouncyCastle. Tal vez sea útil para ti, también.
Si está obteniendo esto cuando intenta enlazar archivos JAR para un proyecto de enlaces de Xamarin.Android, así:
JARTOXML: advertencia J2XA006: se generó un error de clase faltante al reflejar com.your.class: resumen de archivo de firma no válido para los atributos principales del manifiesto
Simplemente abra los archivos JAR utilizando Winzip y elimine los directorios meta-inf. Reconstrucción - trabajo hecho
Suponiendo que construya su archivo jar con ant, puede simplemente indicar a ant que omita el directorio META-INF. Esta es una versión simplificada de mi objetivo 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>
Tuve este problema al utilizar IntelliJ IDEA 14.01.
Pude arreglarlo por:
Archivo-> Estructura del proyecto-> Agregar nuevo (artefactos) -> jar-> Desde módulos con dependencias en la ventana Crear jar desde módulo:
Selecciona tu clase principal
Archivo JAR de las bibliotecas Seleccione copiar al directorio de salida y vincular a través de manifiesto
Tuve un problema similar. La razón fue que estaba compilando usando un JDK con un JRE diferente al predeterminado en mi caja de Windows.
Usando el java.exe correcto solucioné mi problema.
Una estrategia consistiría en usar ANT para simplificar la eliminación de la firma de cada archivo Jar. Se procederá con los siguientes pasos:
- Copiando el MANIFEST.MF en un archivo temporal
- Eliminando las entradas de Nombre y SHA del archivo temporal
- Creando un archivo jar temporal con el manifiesto temporal
- Eliminando el manifiesto temporal.
- Intercambiando el archivo Jar original con el temporal.
Aquí hay un macrodef ANT haciendo el trabajo:
<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 definición se puede llamar de esta manera en una tarea ANT:
<target name="unsignJar">
<unsignjar jarFile="org.test.myjartounsign.jar" />
</target>
Para aquellos que obtuvieron este error al intentar crear un uber-jar con maven-shade-plugin
, la solución es excluir los archivos de firmas de manifiesto agregando las siguientes líneas a la configuración del complemento:
<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>