Google предоставляет удобный API для реализации функций "покупки в приложении" в приложении для Android.
Наряду с этими документами существует также посвященная глава относительно уровня безопасности этой системы и хороших способов ее разработки. В Интернете полно статей об этом шаге от защиты открытых ключей до проверка удаленного сервера, но я действительно не могу понять, почему все эти методы должны работать, когда главная проблема - просто взлом кода.
Может быть, есть лучший термин, чтобы объяснить это, но позвольте мне сделать быстрый пример. Основная идея моего приложения заключается в том, что в определенные моменты пользователь не может действовать, если только он не приобрел элемент.
Что-то вроде:
public void accessTheVeryCoolFeature() {
boolean haveIt = checkIfPurchased("verycoolfeature");
if (haveIt) {
// YEAH! let open this very cool feature I paid 200 bucks for
}
else {
// ok... where is my wallet?
boolean purchased = startPurchaseFlow("verycoolfeature");
if (purchased) {
// my wallet is now empty but happy
}
}
}
Следуя предыдущим рекомендациям, разработчик может защитить свое приложение во время процесса покупки, позволяя методу startPurchaseFlow
запрашивать удаленный, надежный сервер, который проверяет получение.
При этом следует избегать покупок, совершенных с использованием "поддельного рынка".
Другой способ - защитить разблокированный контент, запутывая код. Это очень просто с такими инструментами, как ProGuard, и сделать жизнь "хакера" немного сложнее.
Теперь я попытался выполнить роль хакера, который хочет прочитать мой код, особенно фазу выставления счетов. Мне потребовалось 1 минуту, чтобы определить код, который я написал в предыдущем примере. Теперь лучшая часть: что, если я отредактирую (обфускации) исходный код, чтобы сделать это?
public void atvf() {
boolean hi = cip("verycoolfeature");
hi = true; // <------------------------ AHAH!
if (hi) {
// YEAH! let open this very cool feature for free
}
// ...
}
Все хорошие слова о дистанционной проверке и обфускации кода полностью исчезли. Итак, зачем тратить часы на попытки реализовать их, когда первая проблема находится в логическом значении?
Я что-то пропустил?