代碼說明一切,請直接閱讀代碼。 java
package com.mycompany.myapp5; import android.app.*; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.*; import android.widget.*; import java.io.*; import java.security.cert.CertificateFactory; import java.util.*; import java.security.cert.X509Certificate; import android.content.pm.*; import java.security.MessageDigest; import java.security.cert.*; public class MainActivity extends Activity { ByteArrayOutputStream bos=new ByteArrayOutputStream(); OutputStreamWriter osw=new OutputStreamWriter(bos); PrintWriter pw=new PrintWriter(osw, true); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ScrollView sv=new ScrollView(this); TextView tv=new TextView(this); sv.addView(tv); setContentView(sv); getCertMsg(this.getPackageName()); pw.flush(); tv.setText(bos.toString()); } private void getCertMsg(String packageName) { PackageInfo pis; try { pis = this.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES); Signature[] sigs = pis.signatures; //簽名 pw.println("sigs.len:" + sigs.length); pw.println("sigs[0] data:"); pw.println(toHex(sigs[0].toByteArray())); pw.println(); CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); //獲取證書 X509Certificate cert = (X509Certificate) certFactory.generateCertificate( new ByteArrayInputStream(sigs[0].toByteArray())); //獲取證書發行者 可根據證書發行者來判斷該應用是否被二次打包(被破解的應用從新打包後,簽名與原包必定不一樣,據此能夠判斷出該應用是否被人作過改動) pw.println("cert data:"); pw.println(toHex(cert.getEncoded())); pw.println(); MessageDigest sha1=MessageDigest.getInstance("SHA1"); byte[] bs=sha1.digest(cert.getEncoded()); String certSha1=toHex(bs); MessageDigest md5=MessageDigest.getInstance("md5"); byte[] bs2=md5.digest(cert.getEncoded()); String certMd5=toHex(bs2); pw.println("sha1:"); pw.println(certSha1); pw.println(); pw.println("md5"); pw.println(certMd5); pw.println(); pw.println(cert.getIssuerDN().toString()); pw.println(cert.getSubjectDN().toString()); } catch (CertificateException e) { e.printStackTrace(pw); } catch (Exception e) { e.printStackTrace(pw); } } char[] cs=new char[16]; { for (int i=0;i < 10;i++) { cs[i] = (char) ('0' + i); } for (int i=10;i < 16;i++) { cs[i] = (char) ('A' + i - 10); } } String toHex(byte[] bs) { char[] cs=new char[bs.length * 2]; int x; for (int i=0;i < bs.length;i++) { x = bs[i] & 0xff; cs[2 * i] = this.cs[x / 16]; cs[2 * i + 1] = this.cs[x % 16]; } return new String(cs); } }
上面的cert data=cert.getEncoded()); android
cert data就是pem文件的實際數據,也就是說,pem文件用的Base64編碼,再轉回byte[] 就是certdata了。 app
在上面的例子中,sigs[0].toByteArray()獲得的數據和cert data是同樣的, ide
再說說什麼是pem文件,用過signApk工具的會在該工具的目錄發現有兩個文件,分別是.pem文件和.pk8文件 工具
cert data等於.pem文件的內容的主體部分,也便是-----BEGIN CERTIFICATE-----和-----END CERTIFICATE-----
之間的部分,不包括這兩個標記.BEGIN CERTIFICATE這個標記多是其餘類似的標記,openssl生產的就出現這種狀況。 this
對cert data SHA1摘要就和.pem公鑰證書的SHA1指紋同樣了,同理md5也同樣。 編碼
看到這裏,有人會問,我要的是 keystore證書的指紋,你怎麼跟我討論這個? .net
先別急,keystore證書的指紋和pem公鑰證書的指紋是同樣的,能夠使用openssl將keystore的證書轉成.pem公鑰證書和.pk8私鑰。轉化後證書的指紋信息是同樣的。提供個如何轉化證書的連接 http://blog.csdn.net/ilittleone/article/details/17914995 code
說到這裏,你應該明白了吧。 blog