使用google map api 或者 百度lbs api 需要提交apk 的证书指纹,百度和google 提供的方法如下:
获取到了相关证书指纹,md5 和 sha1 两种hash算法的输出
这种获取方法对于我们来说不是很友好,因为我们app的官方签名手头没有。
我们手头没有官方签名,如何获取呢?
我们只要弄清这是个什么输入即可。
以上两种方法获取到的证书指纹其实是签名用到的公钥hash,不需要使用私钥。也就没必要非要使用原始官方签名文件。
公钥信息可以从打包好的 apk 文件获取。
文件在 apk 的 META-INF\CERT.RSA 或者 META-INF\{keystore.name}.RSA
这个就是对应的公钥信息。格式为 pkcs7封装的 x509 der格式。
有了公钥就可以通过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); }
我们通过PackageManager 获取到应用签名。
PackageInfo pi = pm.getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES); byte[] signature = pi.signatures[0].toByteArray();
获取到的二进制数据对应到上边Java代码的
cert.getEncoded()
也就是x509证书的 ASN1 格式的二进制。