내 Java 프로그램은 jar 파일로 패키지되어 있으며 외부 jar 라이브러리 인 bouncy castle를 사용 합니다. 내 코드는 정상적으로 컴파일되지만 jar를 실행하면 다음 오류가 발생합니다.
스레드 “main”의 예외 java.lang.SecurityException : Manifest 기본 속성에 대한 유효하지 않은 서명 파일 요약
나는 한 시간 이상 설명을 검색하면서 가치가 거의 없었습니다. 누군가이 오류를 전에 본 적이 있고 도움을 줄 수 있다면 나는 의무가 있습니다.
답변
여기에 나열된 솔루션은 포인터를 제공 할 수 있습니다.
결론 :
공식 jar을 그대로 유지하고 응용 프로그램 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을 사용하고 뚱뚱한 항아리를 만들고 사용하려는 경우 다음 구문이 도움이 될 수 있습니다.
jar {
doFirst {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
}
답변
일부 종속성은 서명 된 jar 파일 일 수 있습니다. 그것들을 모두 하나의 큰 jarfile로 결합하면 해당 서명 파일이 여전히 존재하고 더 이상 “큰 결합 된”jar 파일과 일치하지 않으므로 런타임은 jar 파일이 변조되었다고 생각하여 중단됩니다. 말하다).
jarfile 종속성에서 서명 파일을 제거하여 문제점을 해결할 수 있습니다. 불행히도 ant의 한 단계 에서이 작업을 수행 할 수 없습니다 .
그러나 다음을 사용하여 각 jarfile 종속성의 이름을 구체적으로 지정하지 않고 Ant와의 작업을 두 단계로 수행 할 수있었습니다.
<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 요소는 향후 수정 날짜가있는 파일에 대한 오류 를 방지해야합니다 .
연결된 스레드에서 찾은 다른 변형이 작동하지 않았습니다.
답변
다음 명령을 사용하십시오
zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'
답변
IntelliJ IDEA 14.01을 사용할 때이 문제가 발생했습니다.
나는 그것을 고칠 수 있었다 :
모듈에서 Jar 작성 창에 파일-> 프로젝트 구조-> 새 (아티팩트) 추가-> jar-> 종속 모듈이있는 경우 :
메인 클래스를 선택하십시오
라이브러리의 JAR 파일 출력 디렉토리로 사본을 선택하고 매니페스트를 통해 링크
답변
보안은 이미 어려운 주제이지만 가장 인기있는 솔루션은 보안 서명을 삭제하는 것입니다. JCE에는 이러한 서명이 필요합니다 . Maven shade는 서명을 META-INF에 넣는 BouncyCastle jar 파일을 분해하지만 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 서명자 를 사용하는 것 입니다. 이를 통해 보안 오류없이 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 인증서를 가져와야합니다.