有些时候我们需要比对apk包的publickey,获取没有安装的APK包中的publickey可以使用如下的方式:
1 public String collectCertificates(String filePath) {
2 String result = "";
3 try {
4 JarFile jarFile = new JarFile(filePath);
5 Certificate[] certs = null;
6 Enumeration<JarEntry> entries = jarFile.entries();
7 while (entries.hasMoreElements()) {
8 JarEntry je = (JarEntry)entries.nextElement();
9 if (je.isDirectory()) continue;
10 if (je.getName().startsWith("META-INF/")) continue;
11 certs = loadCertificates(jarFile, je);
12
13 if (certs == null) {
14 jarFile.close();
15 return null;
16 }
17 break;
18 }
19 jarFile.close();
20
21 if (certs != null && certs.length > 0) {
22 if (certs[0].getPublicKey().getAlgorithm().equals("DSA")) {
23 result = ((DSAPublicKey)(certs[0].getPublicKey())).getY().toString(16);
24 } else {
25 result = getPublicKey(new Signature(certs[0].getEncoded()).toByteArray());
26 }
27 } else {
28 return null;
29 }
30 } catch (CertificateEncodingException e) {
31 return null;
32 } catch (IOException e) {
33 return null;
34 } catch (RuntimeException e) {
35 return null;
36 }
37
38 return result;
39 }
40
41 private Certificate[] loadCertificates(JarFile jarFile, JarEntry je) {
42 try {
43 byte[] readBuffer = new byte[8192];
44 //必须执行这段代码,对数据从头到尾读一遍,否则下面的getCertificates()返回NULL
45 InputStream is = new BufferedInputStream(jarFile.getInputStream(je));
46 while (is.read(readBuffer, 0, readBuffer.length) != -1) {
47 // not using
48 }
49 is.close();
50 return je != null ? je.getCertificates() : null;
51 } catch (IOException e) {
52 } catch (RuntimeException e) {
53 }
54 return