Re-signing a JAR with Bash

As mentioned previously, we had a little problem at work with a certificate that prompted us to un-sign and re-sign a significant number of jars.

We didn’t have ant available in all production deployments so my co-workers ant macro was unfortunately not appropriate. If you’re in a situation where ant is available, do check it out.

About the only thing we did have was bash and the JDK/JRE. It doesn’t look like the JDK provides any tools to automate the un-signing process , so we resorted to uncompressing and removing all signatures contained within the META-INF directory.

The only kicker resulted from a jar file (jh.jar from JavaHelp) that contained the same resource in the same package multiple times but with different capitalizations (ie. Foo.gif and foo.gif). When uncompressing on a Windows machine, you’ll loose one of the versions due to NTFS being case-insensitive. This caused a bit of grief and we ended up settling on manually signing a fresh copy of the jar that wasn’t previously signed.

Here’s a snippet of what we hacked together (poorly formatted on the web):

!/bin/bash

for i in `find . -name ‘*.jar’`; do
tmp_file=tmp_$$

# Un-sign jar
mkdir $tmpfile
cd $tmp
file

echo “Scrubbing $i”
jar -xf ../$i
if [ -e META-INF ]; then
if [ -e META-INF/*.SF ]; then rm -f META-INF/*.SF; fi
if [ -e META-INF/*.DSA ]; then rm -f META-INF/*.DSA; fi
if [ -e META-INF/*.RSA ]; then rm -f META-INF/*.RSA; fi
fi

echo “Packaging $i”
jar cfM ../$i .
cd ..

echo “Signing $i”
jarsigner -keystore [keystore] -storepass [password] $i [alias]

rm -rf $tmp_file
echo “”
done

Unlike the ant macro, this script won’t necessarly create a META-INF if it didn’t exist previously. If that causes you grief, you’ll want to add a mkdir META-INF ; touch META-INF/MANIFEST.MF prior to the Packaging stage.