一、通过Android方式获取应用签名
使用Android的方式获取签名主要通PackageInfo类直接获取:
/**
* 获取指定应用的签名
*
* @param packageName 包名
* @return 应用对应签名
*/
private String getSign(String packageName) {
try {
PackageInfo info = getPackageManager()
.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
byte[] bytes = info.signatures[0].toByteArray();
return byte2hex(bytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 二进制转换为十六进制字符
*
* @param bytes 二进制数
* @return 十六进制字符
*/
private static String byte2hex(byte[] bytes) {
String hs = "";
String tmp = "";
for (int i = 0; i < bytes.length; i++) {
tmp = (Integer.toHexString(bytes[i] & 0XFF));
if (tmp.length() == 1)
hs = hs + "0" + tmp;
else
hs = hs + tmp;
}
return hs.toUpperCase();
}
二、使用Java的方式获取应用的签名
使用java的方式获取应用签名主要是通过解析apk文件:
/**
* 获取指定apk文件签名
* @param apkFilePath apk文件存储路径
* @return apk文件的签名
*/
public static String getApkSign(String apkFilePath) {
apkFilePath = apkFilePath.trim();
byte[] readBuffer = new byte[8192];
Certificate[] certs = null;
try {
JarFile jarFile = new JarFile(apkFilePath);
Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry je = (JarEntry) entries.nextElement();
// System.out.println("-->" + je.getName());
if (je.isDirectory()) {
continue;
}
if (je.getName().startsWith("META-INF/")) {
continue;
}
Certificate[] localCerts = loadCertificates(jarFile, je, readBuffer);
if (certs == null) {
certs = localCerts;
} else {
for (Certificate cert : certs) {
boolean found = false;
if (localCerts != null) {
for (Certificate localCert : localCerts) {
if (cert != null && cert.equals(localCert)) {
found = true;
break;
}
}
}
if (!found || certs.length != localCerts.length) {
jarFile.close();
return null;
}
}
}
}
jarFile.close();
if (certs != null) {
Certificate cert = certs[0];
// System.out.println(cert.getClass());
// System.out.println("---------------------------------------->");
// System.out.println(cert.toString());
// System.out.println("---------------------------------------->");
byte[] bytes = cert.getEncoded();
String sign = byte2hex(bytes);
// System.out.println(sign);
return sign;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static Certificate[] loadCertificates(JarFile jarFile,
JarEntry je, byte[] readBuffer) {
try {
InputStream is = jarFile.getInputStream(je);
while (is.read(readBuffer, 0, readBuffer.length) != -1) {
}
is.close();
return je.getCertificates();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 二进制转换为十六进制字符
*
* @param bytes 二进制数
* @return 十六进制字符
*/
private static String byte2hex(byte[] bytes) {
String hs = "";
String tmp = "";
for (int i = 0; i < bytes.length; i++) {
tmp = (Integer.toHexString(bytes[i] & 0XFF));
if (tmp.length() == 1)
hs = hs + "0" + tmp;
else
hs = hs + tmp;
}
return hs.toUpperCase();
}
用这种方法若想获取已安装的应用的签名,只需要:
try {
// String packageName = getPackageName();
String packageName = "jackpal.androidterm";
ApplicationInfo ai = getPackageManager().getApplicationInfo(packageName, 0);
String sign2 = getApkSign(ai.sourceDir);
LogUtils.i("-->signature1 : " + sign2);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}