Instantly share code, notes, and snippets.

Embed
What would you like to do?
GetAndroidSig
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.security.cert.CertificateEncodingException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
private static final Object mSync = new Object();
private static WeakReference<byte[]> mReadBuffer;
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Usage: java -jar GetAndroidSig.jar <apk/jar>");
System.exit(-1);
}
System.out.println(args[0]);
String mArchiveSourcePath = args[0];
WeakReference<byte[]> readBufferRef;
byte[] readBuffer = null;
synchronized (mSync) {
readBufferRef = mReadBuffer;
if (readBufferRef != null) {
mReadBuffer = null;
readBuffer = readBufferRef.get();
}
if (readBuffer == null) {
readBuffer = new byte[8192];
readBufferRef = new WeakReference<byte[]>(readBuffer);
}
}
try {
JarFile jarFile = new JarFile(mArchiveSourcePath);
java.security.cert.Certificate[] certs = null;
Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry je = (JarEntry) entries.nextElement();
if (je.isDirectory()) {
continue;
}
if (je.getName().startsWith("META-INF/")) {
continue;
}
java.security.cert.Certificate[] localCerts = loadCertificates(jarFile, je, readBuffer);
if (false) {
System.out.println("File " + mArchiveSourcePath + " entry " + je.getName()
+ ": certs=" + certs + " ("
+ (certs != null ? certs.length : 0) + ")");
}
if (localCerts == null) {
System.err.println("Package has no certificates at entry "
+ je.getName() + "; ignoring!");
jarFile.close();
return;
} else if (certs == null) {
certs = localCerts;
} else {
// Ensure all certificates match.
for (int i = 0; i < certs.length; i++) {
boolean found = false;
for (int j = 0; j < localCerts.length; j++) {
if (certs[i] != null
&& certs[i].equals(localCerts[j])) {
found = true;
break;
}
}
if (!found || certs.length != localCerts.length) {
System.err.println("Package has mismatched certificates at entry "
+ je.getName() + "; ignoring!");
jarFile.close();
return; // false
}
}
}
}
jarFile.close();
synchronized (mSync) {
mReadBuffer = readBufferRef;
}
if (certs != null && certs.length > 0) {
final int N = certs.length;
for (int i = 0; i < N; i++) {
String charSig = new String(toChars(certs[i].getEncoded()));
System.out.println("Cert#: " + i + " Type:" + certs[i].getType()
+ "\nPublic key: " + certs[i].getPublicKey()
+ "\nHash code: " + certs[i].hashCode()
+ " / 0x" + Integer.toHexString(certs[i].hashCode())
+ "\nTo char: " + charSig);
}
} else {
System.err.println("Package has no certificates; ignoring!");
return;
}
} catch (CertificateEncodingException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException e) {
System.err.println("Exception reading " + mArchiveSourcePath + "\n" + e);
return;
} catch (RuntimeException e) {
System.err.println("Exception reading " + mArchiveSourcePath + "\n" + e);
return;
}
}
private static char[] toChars(byte[] mSignature) {
byte[] sig = mSignature;
final int N = sig.length;
final int N2 = N * 2;
char[] text = new char[N2];
for (int j = 0; j < N; j++) {
byte v = sig[j];
int d = (v >> 4) & 0xf;
text[j * 2] = (char) (d >= 10 ? ('a' + d - 10) : ('0' + d));
d = v & 0xf;
text[j * 2 + 1] = (char) (d >= 10 ? ('a' + d - 10) : ('0' + d));
}
return text;
}
private static java.security.cert.Certificate[] loadCertificates(JarFile jarFile, JarEntry je, byte[] readBuffer) {
try {
// We must read the stream for the JarEntry to retrieve
// its certificates.
InputStream is = jarFile.getInputStream(je);
while (is.read(readBuffer, 0, readBuffer.length) != -1) {
// not using
}
is.close();
return (java.security.cert.Certificate[]) (je != null ? je.getCertificates() : null);
} catch (IOException e) {
System.err.println("Exception reading " + je.getName() + " in "
+ jarFile.getName() + ": " + e);
}
return null;
}
}
@blackwat3r

This comment has been minimized.

Show comment
Hide comment
@blackwat3r

blackwat3r Dec 22, 2015

decent approach, I've had to use a similar approach myself to obtain the signature for an app I was attempting to reverse because they rolled their api to utilize the signature to ensure requests originated from their app

blackwat3r commented Dec 22, 2015

decent approach, I've had to use a similar approach myself to obtain the signature for an app I was attempting to reverse because they rolled their api to utilize the signature to ensure requests originated from their app

@psychsecurity

This comment has been minimized.

Show comment
Hide comment
@psychsecurity

psychsecurity Aug 16, 2016

Awesome job ! I've done this manually once with a lot of pain.

psychsecurity commented Aug 16, 2016

Awesome job ! I've done this manually once with a lot of pain.

@chuppito

This comment has been minimized.

Show comment
Hide comment
@chuppito

chuppito Aug 4, 2018

Hello, I got the signature of an application thanks to the tools getandroidsig.
How to be able to put it in file .pk8 and .pem
thank you in advance

chuppito commented Aug 4, 2018

Hello, I got the signature of an application thanks to the tools getandroidsig.
How to be able to put it in file .pk8 and .pem
thank you in advance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment