Asked  6 Months ago    Answers:  5   Viewed   53 times

My java program is packaged in a jar file and makes use of an external jar library, bouncy castle. My code compiles fine, but running the jar leads to the following error:

Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

I've googled for over an hour searching for an explanation and found very little of value. If anyone has seen this error before and could offer some help, I would be obliged.

 Answers

32

The solution listed here might provide a pointer.

Invalid signature file digest for Manifest main attributes

Bottom line :

It's probably best to keep the official jar as is and just add it as a dependency in the manifest file for your application jar file.

Tuesday, June 1, 2021
 
TMichel
answered 6 Months ago
27

Some of your dependency JARs is a signed JAR, so when you combine then all in one JAR and run that JAR then signature of the signed JAR doesn't match up and hence you get the security exception about signature mis-match.

To fix this you need to first identify which all dependency JARs are signed JARs and then exclude them. Depending upon whether you are using MAVEN or ANT, you have to take appropriate solution. Below are but you can read more here, here and here.

Maven:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.6</version>
    <executions>
        <execution>
            <id>unpack-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
                <excludeScope>system</excludeScope>
                <excludes>META-INF/*.SF</excludes>
                <excludes>META-INF/*.DSA</excludes>
                <excludes>META-INF/*.RSA</excludes>
                <excludeGroupIds>junit,org.mockito,org.hamcrest</excludeGroupIds>
                <outputDirectory>${project.build.directory}/classes</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

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>

Update based on OP's comment:

"sqljdbc4.jar" was the signed JAR in OP's external libraries. So, following above approach to systematically exclude the signature related files like .SF, .RSA or .DES or other algorithms files is the right way to move forward.

If these signature files are not excluded then security exception will occur because of signature mismatch.

How to know if a JAR is signed or not?: If a JAR contains files like files like .SF, .RSA or .DES or other algorithms files, then it is a signed JAR. Or run jarsigner -verify jarname.jar and see if it outputs "verified"

Sunday, June 13, 2021
 
SuperString
answered 6 Months ago
91

This used previously to be very common - especially in the days of floppy disks where space was precious and it was tedious for the unzip program to be on a different disk than the zip file.

The reason why it can be done is because the zip-file inventory structure is located at the end of the zip-file, not the front, so a zip file can contain a large number of initial irrelevant bytes as long as the inventory structure does not point to them (and by extension jar-files too). A very frequent use for this has been to enclose a small unzip-only program which could then unpack the zip file.

One utility to prepend such a program is the unzipsfx. Here is a manual page for it: http://linuxcommand.org/man_pages/unzipsfx1.html

It appears that Minecraft uses another prepended program which invokes Java on itself.


EDIT: Looked inside with an hex editor. Minecraft.exe is wrapped with Launch4j.

Wednesday, August 4, 2021
 
Sean Werkema
answered 4 Months ago
57

You are right, there is no source code in the jar (unless you configure your build system to specifically put it in there). But you are always at the risk you code gets decompiled from the bytecode. An obfuscater might help here.

Wednesday, August 25, 2021
 
exebook
answered 3 Months ago
65

I think this should count as a bug in GHC, but there is a workaround. The default encoding for all handles in a GHC program (except those opened in Binary mode) is just the encoding accepted by the console with no error handling. Fortunately you can add error handling with something like this.

makeSafe h = do
  ce' <- hGetEncoding h
  case ce' of
    Nothing -> return ()
    Just ce -> mkTextEncoding ((takeWhile (/= '/') $ show ce) ++ "//TRANSLIT") >>=
      hSetEncoding h

main = do
  mapM_ makeSafe [stdout, stdin, stderr]
  -- The rest of your main function.
Saturday, September 25, 2021
 
Sergey Kucher
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share