Android签名介绍
证书指纹
获取证书指纹
使用google map api 或者 百度lbs api 需要提交apk 的证书指纹,百度和google 提供的方法如下:
1、> keytool –list –v –keystore d:\debug.keystore debug签名密码为 android
2、通过eclipse 获取
获取到了相关证书指纹,md5 和 sha1 两种hash算法的输出
这种获取方法对于我们来说不是很友好,因为我们app的官方签名手头没有。
证书指纹是个什么东西?
我们手头没有官方签名,如何获取呢?
我们只要弄清这是个什么输入即可。
以上两种方法获取到的证书指纹其实是签名用到的公钥hash,不需要使用私钥。也就没必要非要使用原始官方签名文件。
公钥信息可以从打包好的 apk 文件获取。
文件在 apk 的 META-INF\CERT.RSA 或者 META-INF\{keystore.name}.RSA
这个就是对应的公钥信息。格式为 pkcs7封装的 x509 der格式。
通过java获取证书指纹
有了公钥就可以通过java接口来获取证书指纹了
public static void main(String[] args) {
try {
PKCS7 publicKey = new PKCS7(new FileInputStream(new File("CERT.RSA")));
X509Certificate certificate = publicKey.getCertificates()[0];
String sha1FingerPrint = getFingerprint(certificate, "SHA-1");
System.out.println(sha1FingerPrint);
} catch (ParsingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Returns the {@link Certificate} fingerprint as returned by <code>keytool</code>.
*
* @param certificate
* @param hashAlgorithm
*/
public static String getFingerprint(Certificate cert, String hashAlgorithm) {
if (cert == null) {
return null;
}
try {
MessageDigest digest = MessageDigest.getInstance(hashAlgorithm);
return toHexadecimalString(digest.digest(cert.getEncoded()));
} catch(NoSuchAlgorithmException e) {
// ignore
} catch(CertificateEncodingException e) {
// ignore
}
return null;
}
private static String toHexadecimalString(byte[] value) {
StringBuffer sb = new StringBuffer();
int len = value.length;
for (int i = 0; i < len; i++) {
int num = ((int) value[i]) & 0xff;
if (num < 0x10) {
sb.append('0');
}
sb.append(Integer.toHexString(num));
if (i < len - 1) {
sb.append(':');
}
}
return sb.toString().toUpperCase(Locale.US);
}
和apk运行时的Signature怎么对应的
我们通过PackageManager 获取到应用签名。
PackageInfo pi = pm.getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
byte[] signature = pi.signatures[0].toByteArray();
获取到的二进制数据对应到上边Java代码的
cert.getEncoded()
也就是x509证书的 ASN1 格式的二进制。