Подтвердить что ты не робот

Как Google проверяет SHA1 и имя пакета в вызовах API?

При регистрации приложения Android в консоли API для доступа к API Google вы должны ввести свой сертификат отпечатка сертификата SHA1 и имя пакета приложения.

Теперь мне было интересно, как Google может проверить, что эти значения верны, когда вызовы api - это просто простые HTTP-запросы (в простейшем случае, когда вы не используете свой клиент API, который мог бы добавить некоторые значения заголовков)? Вы должны предоставить свой ключ API при вызове API, но это не доказывает правильность введенных значений.

4b9b3361

Ответ 1

Вы можете легко получить имя пакета, а также отпечаток 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();
}

Если вы запустите этот код, он напечатает имя пакета и его печать 1. Это две вещи, которые вы предоставляете при создании ключа API, поэтому Google сопоставляет эти две вещи против создаваемого ключа.

Как вы можете видеть, что его доступ к имени пакета и его SHA 1 печатает, остальная вещь - это ключ API, который вы предоставляете в нужную библиотеку или другое приложение (Служба Google Play) через ваш код или через xml (Manifest, отдельный файл конфигурации xml).

Поэтому всякий раз, когда Google обслуживает вас, он может проверить соответствующее сопоставление, которое оно сгенерировало при создании ключа из консоли API.

Код для имени пакета берется из здесь