"Недопустимый файл подписи" при попытке запуска a.jar

моя программа java упакована в файл jar и использует внешнюю библиотеку jar,надувной замок. Мой код компилируется нормально, но запуск jar приводит к следующей ошибке:

исключение в потоке" main " java.ленг.SecurityException: недопустимый дайджест файла подписи для основных атрибутов Манифеста

я гуглил более часа в поисках объяснения и нашел очень мало ценности. Если кто-то видел эту ошибку и я был бы вам очень обязан, если бы мог предложить помощь.

17 ответов


решение, перечисленное здесь, может предоставить указатель.

недопустимый дайджест файла подписи для основных атрибутов Манифеста

итог :

вероятно, лучше всего сохранить официальную банку как и просто добавить его в качестве зависимостей в файл манифеста файл jar приложения.


для тех, кто получил эту ошибку при попытке создать Убер-фляга С 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>

для тех, кто использует gradle и пытается создать и использовать fat jar, может помочь следующий синтаксис.

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

некоторые из ваших зависимостей, вероятно, подписаны jarfiles. Когда вы объединяете их все в один большой jarfile, соответствующие файлы сигнатур все еще присутствуют и больше не соответствуют "большому объединенному" jarfile, поэтому среда выполнения перестает думать, что файл jar был изменен (который он...имеет так сказать).

вы можете решить проблему, исключив файлы сигнатур из зависимостей jarfile. К сожалению, это невозможно сделать за один шаг в АНТ.

тем не менее, я смог получить эту работу с Ant в два этапа, не называя конкретно каждую зависимость 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>

элемент сна должен предотвращать ошибки о файлах с датами изменения в будущем.

другие варианты, которые я нашел в связанных потоках, не работали для меня.


пожалуйста, используйте следующую команду

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

У меня была эта проблема при использовании IntelliJ IDEA 14.01.

Я смог исправить это:

файл - >структура проекта - >Добавить новый (артефакты)->jar - >из модулей с зависимостями от окна создать Jar из модуля:

выберите основной класс

JAR-файл из библиотек Выберите Копировать в выходной каталог и ссылку через manifest


безопасность уже сложная тема, но я разочарован тем, что самое популярное решение-удалить подписи безопасности. JCE требует эти подписи. Maven shade взрывает файл Jar BouncyCastle, который помещает подписи в META-INF, но подписи 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 shade без получения ошибок безопасности. Однако необходимо иметь сертификат подписи кода (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.


предполагая, что вы создаете свой файл jar с ant, вы можете просто указать ant, чтобы оставить META-INF dir. Это упрощенная версия моей цели 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>

сравните папку META-INF в new jar со старой jar (перед добавлением новых библиотек). Есть вероятность, что появятся новые файлы. Если да, вы можете удалить их. Это должно помочь. С уважением, 999michal


ошибка: произошла ошибка JNI, проверьте установку и повторите попытку Исключение в потоке" main " java.ленг.SecurityException: недопустимый дайджест файла подписи для основных атрибутов Манифеста в Sun.безопасность.утиль.SignatureFileVerifier.processImpl (SignatureFileVerifier.java: 314) в Sun.безопасность.утиль.SignatureFileVerifier.процесс (SignatureFileVerifier.java: 268) на Яве.утиль.сосуд.JarVerifier.processEntry (JarVerifier.java: 316) на Ява.утиль.сосуд.JarVerifier.обновление (JarVerifier.java: 228) на Яве.утиль.сосуд.Файла jarfile.initializeVerifier(файла jarfile.java: 383) на Яве.утиль.сосуд.Файла jarfile.getInputStream(файла jarfile.java: 450) в Sun.разное.URLClassPath$JarLoader$2.getInputStream (URLClassPath.java: 977) в Sun.разное.Ресурс.cachedInputStream (Resource.java: 77) в Sun.разное.Ресурс.getByteBuffer (ресурс.java: 160) в Java.чистая.Urlclassloader, на.defineClass(urlclassloader, на.Ява:454) на Ява.чистая.Urlclassloader, на.доступ к$100(urlclassloader, на.Ява:73) в Java.чистая.Urlclassloader, на$1.запустить(urlclassloader, на.Ява:368) в Java.чистая.Urlclassloader, на$1.запустить(urlclassloader, на.Ява:362) на Яве.безопасность.AccessController.doPrivileged(Native метод) в Java.чистая.Urlclassloader, на.findClass(urlclassloader, на.Ява:361) на Яве.ленг.загрузчик классов.loadClass (загрузчик классов.java: 424) в Sun.разное.Launcher$AppClassLoader.loadClass (пусковая установка.java: 331) на Ява.ленг.загрузчик классов.loadClass (загрузчик классов.java: 357) в Sun.пусковая установка.LauncherHelper.checkAndLoadMain (LauncherHelper.java: 495)

что мне помогло (IntelliJ IDEA 2016.3): Файл - > структура проекта - > артефакты - > добавить JAR - > выберите основной класс - > выберите "Копировать в выходной каталог и ссылку через манифест" - > OK - > применить - > построить - > построить артефакты... - >Построить


У меня была похожая проблема. Причина заключалась в том, что я компилировал с помощью JDK с другой JRE, чем по умолчанию в моем окне Windows.

используя правильный java.exe решил мою проблему.


возможно, что два разных подписчика испортят Java-ум.

Попробуйте удалить папку META-INF из jar, добавив манифест и подписав JAR снова, это помогло мне: http://jehy.ru/articles/2013/12/13/invalid-signature-file-digest-for-manifest-main-attributes/


стратегия будет состоять в использовании ANT для упрощения удаления подписи из каждого файла Jar. Он будет действовать следующим образом:

  1. копирование манифеста.MF во временном файле
  2. удаление имя и ша записи из временного файла
  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>

недавно я начал использовать IntelliJ в своих проектах. Однако некоторые из моих коллег все еще используют Eclipse в тех же проектах. Сегодня у меня такая же ошибка после выполнения jar-файла, созданного моим IntelliJ. Хотя все решения здесь говорят почти об одном и том же, ни одно из них не работало для меня легко (возможно, потому, что я не использую ANT, Maven build дал мне другие ошибки, которые ссылались на меня http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException, а также я не мог понять, что такое подписанные банки самостоятельно!)

наконец, этой помог мне

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.


Если вы получаете это при попытке связать файлы JAR для Xamarin.Проект Привязок Android выглядит так:

JARTOXML: предупреждение J2XA006: ошибка отсутствующего класса была вызвана при отражении com.ваш.класс: недопустимый дайджест файла подписи для основных атрибутов Манифеста

просто откройте файлы JAR с помощью Winzip и удалите каталоги meta-inf. Восстановить работу


Если вы используете 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
}

Если вы ищете решение Fat JAR без распаковки или изменения исходных библиотек, но со специальным загрузчиком классов JAR, взгляните на мой проект здесь.

отказ от ответственности: я не писал код, просто упакуйте его и опубликуйте на Maven Central и опишите в моем read-me, как его использовать.

Я лично использую его для создания runnable Uber JARs, которые содержат зависимости BouncyCastle. Может быть, это полезно и для вас.