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

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

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

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

Ответ 1

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

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

Нижняя строка:

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

Ответ 2

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

Ответ 3

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

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

Ответ 4

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

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

Тем не менее, мне удалось выполнить эту работу с 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>

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

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

Ответ 5

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

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

Ответ 6

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

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

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

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

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

Ответ 7

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

ОБНОВЛЕНИЕ:

Другой способ сделать это (правильный путь?) - использовать 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

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

Ответ 9

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

<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>

Ответ 10

Я недавно начал использовать 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'

Угадай, что было удалено из моего фляги?!

deleting: META-INF/ECLIPSE_.SF 
deleting: META-INF/ECLIPSE_.RSA

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

Ответ 11

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

Ответ 12

Ошибка: произошла ошибка JNI, проверьте свою установку и повторите попытку Исключение в потоке "main" java.lang.SecurityException: Недопустимый дайджест файла подписи для основных атрибутов манифеста     at sun.security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.java:314)     at sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.java:268)     в java.util.jar.JarVerifier.processEntry(JarVerifier.java:316)     в java.util.jar.JarVerifier.update(JarVerifier.java:228)     в java.util.jar.JarFile.initializeVerifier(JarFile.java:383)     в java.util.jar.JarFile.getInputStream(JarFile.java:450)     at sun.misc.URLClassPath $JarLoader $2.getInputStream(URLClassPath.java:977)     at sun.misc.Resource.cachedInputStream(Resource.java:77)     at sun.misc.Resource.getByteBuffer(Resource.java:160)     в java.net.URLClassLoader.defineClass(URLClassLoader.java:454)     на java.net.URLClassLoader.access $100 (URLClassLoader.java:73)     на java.net.URLClassLoader $1.run(URLClassLoader.java:368)     на java.net.URLClassLoader $1.run(URLClassLoader.java:362)     в java.security.AccessController.doPrivileged(собственный метод)     в java.net.URLClassLoader.findClass(URLClassLoader.java:361)     в java.lang.ClassLoader.loadClass(ClassLoader.java:424)     at sun.misc.Launcher $AppClassLoader.loadClass(Launcher.java:331)     в java.lang.ClassLoader.loadClass(ClassLoader.java:357)     на sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

Что мне помогло (IntelliJ IDEA 2016.3): Файл → Структура проекта → Артефакты → Добавить JAR → Выбрать главный класс → Выбрать "скопировать в выходной каталог и связать через манифест" → OK → Применить → Сборка → Сборка артефактов... → Сборка

Ответ 13

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

Ответ 15

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

  • Копирование файла MANIFEST.MF во временный файл
  • Удаление записей имени и SHA из временного файла
  • Создание временного файла Jar с временным манифестом
  • Удаление временного манифеста
  • Обмен исходным файлом 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>

Ответ 16

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

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

Я лично использую его для создания исполняемых UAR-JAR файлов, содержащих зависимости BouncyCastle. Может быть, это тоже полезно для вас.

Ответ 17

У меня была та же проблема в gradle при создании толстого Jar, обновление файла build.gradle с помощью строки исключения исправило проблему.

jar {
    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
    manifest {
        attributes 'Main-Class': 'com.test.Main'
    }
}

Ответ 18

Для тех, у кого проблемы с принятым решением, есть другой способ исключить ресурс из затененной банки с помощью DontIncludeResourceTransformer:

https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html#DontIncludeResourceTransformer

          <transformers>
            <transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
                <resource>BC1024KE.DSA</resource>
            </transformer>
          </transformers>

От Shade 3.0 этот преобразователь принимает список ресурсов. Перед этим вам просто нужно использовать несколько трансформаторов, каждый с одним ресурсом.

Ответ 19

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

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

Ответ 20

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

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

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