ebourg / jsign

Java implementation of Microsoft Authenticode for signing Windows executables, installers & scripts
https://ebourg.github.io/jsign
Apache License 2.0
250 stars 107 forks source link

Jsign corrupts launch4j bundled jar within exe container #80

Closed falkzilm-nuclos closed 1 year ago

falkzilm-nuclos commented 4 years ago

I have a maven build with following steps:

Build works properly, in windows i can see that the executable has a signature added with conforms to my certificat.

But im unable to execute it anymore i get following error:

image

Does somebody has an idea for debugging or hints how to avoid this? I saw somebody writing and using sign4j.exe from https://github.com/fbergmann/launch4j/tree/master/sign4j

Does this the trick, why does jsign supports launcher4j but seems not work then?

BR, Falk

ebourg commented 4 years ago

What version of Java do you use?

falkzilm-nuclos commented 4 years ago

I was using java 8 (1.8.0_241)

ebourg commented 4 years ago

Interesting, this issue has already been reported (#4) but with Java 6 only. As far as I understand there is something wrong with the way launch4j loads the embedded jar since this error never happens with other executable wrappers such as exe4j.

falkzilm-nuclos commented 4 years ago

So reading this thread lead me to the assumption it is launch4j which does bad stuff, is this right? Changing to e.g exe4j could solve the issue then?

ebourg commented 4 years ago

I've reproduced the issue by wrapping the jsign jar into an executable generated by launch4j 3.12. It failed with Java 8u251 and OpenJDK 14.

Java seems to be a bit picky when loading jar files, a single byte appended to the file and it's no longer possible to run it with java -jar. But java -cp myapp.jar org.acme.Main still works (starting with Java 7, Java 6 throws a ClassNotFoundException).

It's possible to append up to 64K bytes to the jar as a ZIP comment in the end of central directory record. It's just a matter a specifying the lengh of the comment in the last two bytes of the file. That's what the patch suggested in #4 does, as well as the sign4j tool provided by launch4j. But this is not a very good workaround, because the file has to be signed twice (first to compute the size of the signature block, and then to sign the file with the zip comment length modified), it isn't guaranteed to work (the size of the second signature block could be different), and it's impossible to add multiple signatures since a new signature changes the content of the file and invalidates the previous signatures.

There is a good news though, since java -cp works with a modified jar, it's possible to work around the issue by setting the main class in the launch4j configuration:

<classPath>
  <mainClass>org.acme.Main</mainClass>
</classPath>

Could you give it a try?

falkzilm-nuclos commented 4 years ago

This really did the trick. This is a workaround i clearly could live with, better then compiling some external program to do weird signing stuff.

And you are completely right with your explanation from my point of view.

gillg commented 3 years ago

Finaly what is the trick here ? I have the same issue.

Use java -cp .\jsign-4.0-SNAPSHOT.jar net.jsign.JsignCLI instead of java -jar .\jsign-4.0-SNAPSHOT.jar ?

It seems not really better for me.

ebourg commented 3 years ago

The workaround is to specify the main class in the launch4j configuration.

gillg commented 3 years ago

Ah ok ! So I have to rethink it, for now the lanch4j build and signing phase are completely decoralated, in different place, different country, made by different teams... 😅 If in the meantime you find a stable solution or another workaround I take it !

ebourg commented 3 years ago

I can't do much on the Jsign side unfortunately, that's really a launch4j flaw. Your best bet is to have the team responsible for building the .exe to change the launch4j configuration (or switch to an alternative such as exe4j).

gillg commented 3 years ago

Sorry I was completly missed... I just understood it's the wrapping command which the "exe" lauch with launch4j. It's not question to embded jsign in the launch4j project...

Sorry ! I understand !