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

Защита покупок в приложении от Freedom Hack

Я полностью просмотрел этот сайт, а также другие ответы и не нашел фактического.

Мой вопрос в том, что именно делает Freedom Hack (что позволяет пользователям получать покупки в приложении без оплаты). То есть какая часть процесса изменяется. Я нашел этот список приложений, для которых работает хак, а некоторые из записей, датированных этим месяцем, означают, что он еще не был полностью исправлен, Ответы, которые я видел, были "проверкой приложения на вашем сервере", но если взломать, например, изменяет функцию проверки подписи Java.Security, поэтому она всегда возвращает значение true, а затем добавление моей собственной сигнатуры на сервере не будет много помогите.

4b9b3361

Ответ 1

Я не знаю, продолжает ли автор следовать этой теме или нет. Но я провел некоторое время, чтобы узнать (googling), как работает свобода и как ее предотвращать (пока они не обновляют способ свободы) в моем проекте, и это работает. Моя реализация очень проста, и вам не нужно проверять, отправив запрос на сервер (что влияет на производительность и прикладывает больше усилий для ее реализации).

Текущая реализация свободы заключается в том, что она заменит (перенаправляет) все вызовы метода java.security.Signature.verify(byte[]) на метод свободы jni, который в свою очередь просто просто возвращает true (or 1).

Взгляните на java.security.Signature.verify(byte[]):

 public final boolean verify(byte[] signature) throws SignatureException {
        if (state != VERIFY) {
            throw new SignatureException("Signature object is not initialized properly");
        }
        return engineVerify(signature);
    }

Здесь метод engineVerify - это метод abstract protected, который сначала определяется в java.security.SignatureSpi (Signature extends SignatureSpi). Хорошо, это достаточно, потому что я больше не могу поверить методу java.security.Signature.verify(byte[]), я бы использовал метод engineVerify напрямую. Для этого нам нужно использовать отражение. Измените метод verify IABUtil/Security на:

public static boolean verify(PublicKey publicKey, String signedData, String signature) {
        Signature sig;
        try {
            sig = Signature.getInstance(SIGNATURE_ALGORITHM);
            sig.initVerify(publicKey);
            sig.update(signedData.getBytes());
            if (!sig.verify(Base64.decode(signature))) {
                Log.e(TAG, "Signature verification failed.");
                return false;
            }
            return true;
        } catch (...) {
            ...
        }
        return false;
    }

To:

public static boolean verify(PublicKey publicKey, String signedData, String signature) {
        Signature sig;
        try {
            sig = Signature.getInstance(SIGNATURE_ALGORITHM);
            sig.initVerify(publicKey);
            sig.update(signedData.getBytes());
            Method verify = java.security.SignatureSpi.class.getDeclaredMethod("engineVerify", byte[].class);
            verify.setAccessible(true);
            Object returnValue = verify.invoke(sig, Base64.decode(signature));
            if (!(Boolean)returnValue) {
                Log.e(TAG, "Signature verification failed.");
                return false;
            }
            return true;
        } catch (...) {
            ...
        }
        return false;
    }

Это просто, но он работает с текущей реализацией свободы, пока не обновит свой алгоритм в будущем.

Ответ 2

тогда добавление моей собственной сигнатуры на сервере не поможет.

Это неверно, подпись, которую использует "Свобода", недопустима, и идентификатор заказа также недействителен.

Что я сделал для обеспечения безопасности моего приложения:

  • Отправьте isPurchaseValid(myPurchase.getSignature(), myPurchase.getOriginalJson()) на мой сервер, чтобы проверить там, и он работает с реальными покупками, но свобода не срабатывает каждый раз.

  • На сервере я проверяю, соответствует ли подпись

  • Если это соответствует, свяжитесь со "API API Google API для Google Android для Android" и "androidpublisher.inapppurchases.get", чтобы убедиться, что покупка существует и которая возвращает полезную нагрузку моего разработчика.

  • Затем я использую полезную нагрузку разработчика, чтобы убедиться, что эта покупка для этого конкретного пользователя, а не какого-либо другого пользователя, и этот пользователь отправляет мне свои данные.

P.S. Полезная нагрузка разработчика - это String, которую вы установили до того, как покупка сделана из вашего приложения Android, это должно быть что-то уникальное для вашего пользователя.

Это может быть много работы, но это гарантирует, что никто не будет покупать ваши вещи со свободой и преуспеть.

Единственное, что я не могу сделать, это не позволить свободе влиять на мое приложение, например, люди в Path сделали что-то, что я не знаю, что сделало Freedom недействительным, что так всегда!!!!

Ответ 3

Я использую что-то вроде этого, я знаю, что это нехорошее решение по сравнению с проверкой удаленного сервера для вашей подписи. Я проверяю, установлено ли приложение Freedom, если это так, я не открываю свое приложение.

@Override
protected void onCreate(Bundle arg0) {
    super.onCreate(arg0);
    if(isHackerAppIsntalled())
        finish();
}

private boolean isHackerAppInstalled() {        
    final PackageManager pm = getApplication().getPackageManager();
    List<ApplicationInfo> packages = pm
            .getInstalledApplications(PackageManager.GET_META_DATA);
    for (ApplicationInfo packageInfo : packages) {
        String packageName = packageInfo.packageName;
        if (packageName.contains("cc.madkite.freedom")
                || packageName.contains("madkite.freedom")) {
            return true;
        }
    }
    return false;
}