在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(); } } }
相关文章推荐
- Android设计模式系列(10)--SDK源码之原型模式
- android4.4短信拦截怎么实现,abortBroadcast()不能实现啊
- android GridLayout。。。
- Activity的跳转
- android中MeasureSpec的使用
- Android AutoLayout全新的适配方式 堪称适配终结者
- Android设计模式系列(9)--SDK源码之适配器模式
- Android 编程下获得应用程序的签名
- Android设计模式系列(8)--SDK源码之工厂方法模式
- android 拍照 图片剪切
- Android二维码的扫描和生成(ZXing)
- Android PRODUCT_COPY_FILE宏 使用方法
- 想要阻断短信通知必须成为android4.4默认短信应用,并且阻断两种广播才能做到
- Android控件的坑
- Android进程间通信(IPC)机制Binder简要介绍和学习plan
- ArcGIS4Android 3 :最快Android模拟器Genymotion
- Android基础-Notification用法
- Android中糟糕的AsyncTask
- android LayoutInflater使用
- 一步一步开发安卓应用 Android 启动界面的制作