«Неверный файл подписи» при попытке запустить .jar - PullRequest
415 голосов
/ 16 июня 2009

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

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

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

Ответы [ 19 ]

1002 голосов
/ 19 июля 2011

Для тех, кто получил эту ошибку при попытке создать uber-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>
126 голосов
/ 21 января 2013

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

jar {
    doFirst {
        from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' 
}
55 голосов
/ 14 декабря 2011

Некоторые из ваших зависимостей, вероятно, являются подписанными jarfiles. Когда вы объединяете их в один большой jar-файл, соответствующие файлы сигнатур по-прежнему присутствуют и больше не соответствуют «большому объединенному» jar-файлу, поэтому среда выполнения останавливается, думая, что файл 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>

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

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

46 голосов
/ 09 июня 2016

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

zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'
46 голосов
/ 16 июня 2009

В указанном здесь решении может быть указатель.

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

Итог:

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

25 голосов
/ 11 декабря 2014

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

Мне удалось это исправить:

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

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

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

13 голосов
/ 02 сентября 2017

Безопасность - это уже сложная тема, но я разочарован тем, что самым популярным решением является удаление сигнатур безопасности. JCE требует эти подписи . Maven shade использует файл Jar BouncyCastle, который помещает подписи в META-INF, но подписи BouncyCastle недопустимы для нового uber-jar (только для jar BC), и именно поэтому вызывает ошибку подписи Invalid в этой теме .

Да, исключение или удаление подписей в соответствии с предложением @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 в одном исполняемом банке.

UPDATE

Другой способ сделать это (правильный путь?) - использовать Maven Jar signer . Это позволяет вам продолжать использовать тени Maven без ошибок безопасности. ОДНАКО, у вас должен быть сертификат подписи кода (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.

8 голосов
/ 05 сентября 2010

Предполагая, что вы создаете свой jar-файл с помощью ant, вы можете просто дать команду ant пропустить каталог META-INF. Это упрощенная версия моей цели муравья:

<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>
5 голосов
/ 12 марта 2019

Я столкнулся с той же проблемой, после ссылки где-то это работало, как показано ниже:

<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>
2 голосов
/ 09 июня 2018

Я недавно начал использовать IntelliJ в своих проектах. Однако некоторые из моих коллег все еще используют Eclipse в тех же проектах. Сегодня я получил ту же ошибку после выполнения jar-файла, созданного моим IntelliJ. Хотя все решения, о которых здесь говорится, говорят об одном и том же, ни одно из них не сработало для меня легко (возможно, из-за того, что я не использую ANT, сборка maven вызвала у меня другие ошибки, которые привели меня к 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

Похоже, проблема была связана с некоторыми файлами, относящимися к затмению.

...