您的位置:首页 > 移动开发 > Android开发

在Android系统外部和内部读取Android应用的签名

2016-03-14 17:18 836 查看
Android系统外读取签名(J2SE):

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.security.Signature;
import java.security.cert.*;
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]);

//To char: 3082023f308201a8a00302010202044c984ccc300d06092a864886f70d01010505003064310b300906035504061302434e3110300e060355040813074a69616e6773753110300e060355040713074e616e6a696e6731153013060355040a130c456d6167736f667477617265310d300b060355040b13045469616e310b3009060355040313024c75301e170d3130303932313036313232385a170d3338303230363036313232385a3064310b300906035504061302434e3110300e060355040813074a69616e6773753110300e060355040713074e616e6a696e6731153013060355040a130c456d6167736f667477617265310d300b060355040b13045469616e310b3009060355040313024c7530819f300d06092a864886f70d010101050003818d0030818902818100835c192e7385ff63ab7bc8469df0224caac1eeea054e6a9bca9d7f3915db090b2bc3cde0f587da732fe45ce55dba30fe3cda5dfbb9797d7b05d59794916d61d5678b3a40722eb09ede89f1e4135a289a8a8464de19d6aab2f2bd8a702e6f53107ef51f25985bdca1a8572eed13827aaf96f8fcfaefe00d31881058134964fd970203010001300d06092a864886f70d01010505000381810072881563e0b07637bf03a6862e3dd9e7dd7186a3355639937748a686119ad59a612a95c6eb8b87b05d0353fc69eefe1b195eafaa08c08f1bf4d20659821ed67fd93d387912af03589d42551affbb6bdfdf81c4e702b32df611a9fcc8ad309edc02d694c948690258245e429bfd0049fd65e284c35d86e046a8abb0a4ee218eff

args = new String[1];
args[0] = "WheresMyWater-12-16-11-PCL989699-signed.apk";

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 (true) {
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;
}
}
Android系统内读取签名:

package cn.emagsoftware.test;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.webkit.WebView;
import android.widget.TextView;

public class Test extends Activity {

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;
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

try {
//            //01-30 21:11:07.507: I/System.out(23733): 177496438 / 0xa946176
//            //01-30 21:39:36.702: I/System.out(26332): 3082023f308201a8a00302010202044c984ccc300d06092a864886f70d01010505003064310b300906035504061302434e3110300e060355040813074a69616e6773753110300e060355040713074e616e6a696e6731153013060355040a130c456d6167736f667477617265310d300b060355040b13045469616e310b3009060355040313024c75301e170d3130303932313036313232385a170d3338303230363036313232385a3064310b300906035504061302434e3110300e060355040813074a69616e6773753110300e060355040713074e616e6a696e6731153013060355040a130c456d6167736f667477617265310d300b060355040b13045469616e310b3009060355040313024c7530819f300d06092a864886f70d010101050003818d0030818902818100835c192e7385ff63ab7bc8469df0224caac1eeea054e6a9bca9d7f3915db090b2bc3cde0f587da732fe45ce55dba30fe3cda5dfbb9797d7b05d59794916d61d5678b3a40722eb09ede89f1e4135a289a8a8464de19d6aab2f2bd8a702e6f53107ef51f25985bdca1a8572eed13827aaf96f8fcfaefe00d31881058134964fd970203010001300d06092a864886f70d01010505000381810072881563e0b07637bf03a6862e3dd9e7dd7186a3355639937748a686119ad59a612a95c6eb8b87b05d0353fc69eefe1b195eafaa08c08f1bf4d20659821ed67fd93d387912af03589d42551affbb6bdfdf81c4e702b32df611a9fcc8ad309edc02d694c948690258245e429bfd0049fd65e284c35d86e046a8abb0a4ee218eff
PackageInfo pis = this.getPackageManager().getPackageInfo("com.xx.xx", PackageManager.GET_SIGNATURES);
Signature[] sigs = pis.signatures;

System.out.println("version code=" + pis.versionCode);
System.out.println(sigs[0].hashCode()+ " / 0x" + Integer.toHexString(sigs[0].hashCode()));
String sig = new String(sigs[0].toChars());
System.out.println("to Char "+sig.length()+" length: " + sig);

String apk = "/sdcard/xx.apk";
PackageInfo pi = this.getPackageManager().getPackageArchiveInfo(apk, PackageManager.GET_SIGNATURES);

String main = new String(pi.signatures[0].toChars());
System.out.println("to Char "+main.length()+" apk:" + main);
System.out.println(main.equals(sig));
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: