java - Google 如何验证 API 调用中的 SHA1 和程序包名称?

标签 java android security google-api google-authentication

在 API 控制台中注册 Android 应用程序以访问 Google API 时,您必须输入应用程序的 SHA1 证书指纹和应用程序包名称。

现在我想知道当 api 调用只是简单的 HTTP 请求时 Google 如何验证这些值是否正确(在最简单的情况下,当您不使用他们的 API 客户端时,可以附加一些 header 值)?您必须在进行 API 调用时提供您的 API key ,但这并不能证明输入的值是正确的。

最佳答案

您可以很容易地获取包名以及已安装应用程序的 sha 1 指纹。

private void printSha1() {
    List<ApplicationInfo> mAppList = getPackageManager().getInstalledApplications(0);
    for (ApplicationInfo info :mAppList) {
        Log.d(TAG, "Package Name: " + info.packageName);
        Log.d(TAG, "Sha1: " + getCertificateSHA1Fingerprint(info.packageName));
    }
}

private String getCertificateSHA1Fingerprint(String packageName) {
    PackageManager pm = getPackageManager();
    int flags = PackageManager.GET_SIGNATURES;
    PackageInfo packageInfo = null;
    try {
        packageInfo = pm.getPackageInfo(packageName, flags);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    Signature[] signatures = packageInfo.signatures;
    byte[] cert = signatures[0].toByteArray();
    InputStream input = new ByteArrayInputStream(cert);
    CertificateFactory cf = null;
    try {
        cf = CertificateFactory.getInstance("X509");
    } catch (CertificateException e) {
        e.printStackTrace();
    }
    X509Certificate c = null;
    try {
        c = (X509Certificate) cf.generateCertificate(input);
    } catch (CertificateException e) {
        e.printStackTrace();
    }
    String hexString = null;
    try {
        MessageDigest md = MessageDigest.getInstance("SHA1");
        byte[] publicKey = md.digest(c.getEncoded());
        hexString = byte2HexFormatted(publicKey);
    } catch (NoSuchAlgorithmException e1) {
        e1.printStackTrace();
    } catch (CertificateEncodingException e) {
        e.printStackTrace();
    }
    return hexString;
}

public static String byte2HexFormatted(byte[] arr) {
    StringBuilder str = new StringBuilder(arr.length * 2);
    for (int i = 0; i < arr.length; i++) {
        String h = Integer.toHexString(arr[i]);
        int l = h.length();
        if (l == 1) h = "0" + h;
        if (l > 2) h = h.substring(l - 2, l);
        str.append(h.toUpperCase());
        if (i < (arr.length - 1)) str.append(':');
    }
    return str.toString();
}

如果您运行此代码,它将打印包名称及其 sha 1 打印。这是您在创建 API key 时提供的两件事,因此 Google 将这两件事映射到它生成的 key 。

如您所见,可以访问包名称及其 SHA 1 打印,剩下的另一件事是您通过代码或通过 xml( list ,单独的 xml 配置文件)。

因此,每当 Google 为您提供任何服务时,它都可以检查您从 API 控制台生成 key 时生成的相关映射。

包名代码取自here

关于java - Google 如何验证 API 调用中的 SHA1 和程序包名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25875845/

相关文章:

java - 记录/记录数据库更新、访问、修改等的最后日期/时间的简单方法

android - 当 setBuiltInZoomControls 在 android 的 webview 中为真时,ontouch 不起作用

android - 导航预览/编辑器未显示

ios - iOS Secure Enclave 中可以存储多少个 key ?

java - 使用 swing Timer 在 JFrame 之间切换

java - Android ACTION_UP 在 ACTION_MOVE 之后不会被触发

node.js - 保护 POST 请求

security - 我如何知道 Mac OS X 中的进程数据包来自哪个进程?

java - 导入和扩展类有什么区别?

android - Flutter 使用 C/C++ 代码构建 - 示例?