[java] .jar를 실행하려고 할 때“잘못된 서명 파일”

내 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 인증서를 가져와야합니다.