Menu

#190 Dual-signing sometimes result in a corrupted jar file error

3.x
open
nobody
None
5
2025-06-26
2018-07-06
No

When signing an executable (about 18MB) with sign4j the result sometimes corrupt the jarfile.

Discussion

  • Warren Prescott

    Warren Prescott - 2018-07-09

    I think I'm also experiencing this

     

    Last edit: Warren Prescott 2018-07-09
  • Markus Gothe

    Markus Gothe - 2018-08-09

    Actually I get this BEFORE signing:
    Current PE checksum : 00018890
    Calculated PE checksum: 011E2EDA MISMATCH!!!!

     
  • Markus Gothe

    Markus Gothe - 2018-08-10

    I found out that the temporary file and the infile might differ in file size and this causing the error. Below is my fix for it.

     
  • Markus Gothe

    Markus Gothe - 2018-08-11

    A note should be made that the patch only makes sign4j to return -1 if the file sizes doesn't match , so one might want to recreate the executable and retry to sign it in the CD-pipeline / build

     

    Last edit: Markus Gothe 2018-08-11
  • Grzegorz Kowal

    Grzegorz Kowal - 2018-08-11

    Thanks for the patch, I will have a look.

     
  • David Tuma

    David Tuma - 2025-06-09

    I've been experiencing this too. Unfortunately it is nondeterministic; sometimes it works and sometimes it doesn't. When it works the file is signed successfully; when it doesn't, running the EXE results in an error message "Invalid or corrupt jarfile" from the launched javaw.exe process. Nothing in my build process changes; I can run the build again, and it might work the next time or it might not. Overall my success rate is only about 50%.

    The worst problem is that I can't detect this failure in my build process. The sign4j step completes successfully and returns a 0 exit code. I have to go back at the end of the build and manually run all the EXEs that were generated to see if they are corrupt. Then resign the corrupt files again, manually repeating and testing in a loop, until I get a version that isn't corrupt. It means my CI pipeline can't be trusted, and I risk releasing a corrupt file without constant diligence.

    Looking at Markus's patch, it makes me wonder if some signing algorithms add a signature that can vary in size from one run to the next?

    I'm using jsign version 7.0 (not the 2.0 version bundled in launch4j) because I needed support for Azure Trusted Signing. If it helps, I can share a copy of the unsigned exe that launch4j produced (which works fine) along with corrupt and successful versions produced by sign4j.

     

    Last edit: David Tuma 2025-06-09
  • David Tuma

    David Tuma - 2025-06-26

    After testing, I was able to verify the root cause I suspected earlier: the size of the appended signature can change from one run to the next. Timestamping could be a contributing factor.

    Fortunately, the size isn't completely unstable; it usually differs by a few bytes, and toggles between two (or occasionally three) possibilities. This makes it feasible to produce a successful signature by iterating until the sizes match in two consecutive runs.

    I took a look at modifying the original sign4j.c program, but C isn't my forte. Since all users of launch4j are Java developers anyway, I wrote a Java version of the sign4j utility that includes a fix for this bug. I took care to make sure I was command-line compatible with the original C version, so it works as a drop-in replacement. I also added an Ant task. I've published it here: https://github.com/dtuma/sign4j-java

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.