chiark / gitweb /
A little utility to calculate an md5 sum of an APK's signature in a form that matches...
authorCiaran Gultnieks <ciaran@ciarang.com>
Fri, 14 Jan 2011 23:11:12 +0000 (23:11 +0000)
committerCiaran Gultnieks <ciaran@ciarang.com>
Fri, 14 Jan 2011 23:11:12 +0000 (23:11 +0000)
getsig/getsig.java [new file with mode: 0644]
getsig/make.sh [new file with mode: 0755]
getsig/run.sh [new file with mode: 0755]

diff --git a/getsig/getsig.java b/getsig/getsig.java
new file mode 100644 (file)
index 0000000..8b1da1e
--- /dev/null
@@ -0,0 +1,88 @@
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.Signature;
+import java.security.cert.*;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+public class getsig {
+    public static void main(String[] args) {
+
+        if (args.length != 1) {
+            System.out.println("Specify the APK file to get the signature from!");
+            System.exit(1);
+        }
+        String apkPath = args[0];
+        try {
+
+            JarFile apk = new JarFile(apkPath);
+            java.security.cert.Certificate[] certs = null;
+            Enumeration entries = apk.entries();
+            while (entries.hasMoreElements()) {
+                JarEntry je = (JarEntry) entries.nextElement();
+                if (!je.isDirectory() && !je.getName().startsWith("META-INF/")) {
+                    // Just need to read the stream (discarding the data) to get
+                    // it to process the certificate...
+                    byte[] b = new byte[4096];
+                    InputStream is = apk.getInputStream(je);
+                    while (is.read(b, 0, b.length) != -1);
+                    is.close();
+                    certs = je.getCertificates();
+                    if(certs != null)
+                        break;
+                }
+            }
+            apk.close();
+
+            if (certs == null) {
+                System.out.println("Not signed");
+                System.exit(1);
+            }
+            if (certs.length != 1) {
+                System.out.println("One signature expected");
+                System.exit(1);
+            }
+
+            // Get the signature in the same form that is returned by
+            // android.content.pm.Signature.toCharsString() (but in the
+            // form of a byte array so we can pass it to the MD5 function)...
+            byte[] sig = certs[0].getEncoded();
+            byte[] csig = new byte[sig.length * 2];
+            for (int j=0; j<sig.length; j++) {
+                byte v = sig[j];
+                int d = (v>>4)&0xf;
+                csig[j*2] = (byte)(d >= 10 ? ('a' + d - 10) : ('0' + d));
+                d = v&0xf;
+                csig[j*2+1] = (byte)(d >= 10 ? ('a' + d - 10) : ('0' + d));
+            }
+
+            // Get the MD5 sum of that...
+            MessageDigest md;
+            md = MessageDigest.getInstance("MD5");
+            byte[] md5sum = new byte[32];
+            md.update(csig);
+            md5sum = md.digest();
+            BigInteger bigInt = new BigInteger(1, md5sum);
+            String md5hash = bigInt.toString(16);
+            while (md5hash.length() < 32)
+                md5hash = "0" + md5hash;
+            System.out.println("Result:" + md5hash);
+            System.exit(0);
+
+        } catch (Exception e) {
+            System.out.println("Exception:" + e);
+            System.exit(1);
+        }
+    }
+
+}
+
+
diff --git a/getsig/make.sh b/getsig/make.sh
new file mode 100755 (executable)
index 0000000..aa63c1a
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+javac getsig.java
diff --git a/getsig/run.sh b/getsig/run.sh
new file mode 100755 (executable)
index 0000000..726995b
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+java getsig $1 $2 $3