Ты всё правильно рассуждаешь.
Исходить из принципа: все клиенты - мошенники.
0% доверия клиенту.
Не хранить у клиента никакой информации.
Клиент - это только рендеринг данных.
Вся логика - на сервере.
Вся логика на сервере. Клиенту отдаются только соевые данные для рендеринга.
Интересует. как в андроид приложениях защититься от подмены данных отправляемых на сервер и быть уверенным, что каждая игра будет честной и без читерства.
Защита от подмены данных делается простым старым дедовским способом - подписью.
На сервере и на клиенте есть одинаковый временный ключ для подписи - signKey - длинная строка.
Клиент отправляет тебе POST-запрос со всеми данными: тип монеты, количество монет, ID юзера,...+ sign=HASH(тип_монеты+количество+userId+...+signKey)
HASH - это хэш-функция. Лучше использовать Bcrypt вместо слабого MD5.
Во-первых, всё делается через HTTPS.
Во-вторых, все операции - через сессии или аутентификацию по JWT.
На сервере ты делашь следующее:
- проверяешь соответствие переданных данных ожидаемым: userId (из JWT), тип монеты и прочее. От клиента ты ожидаешь МИНИМУМ изменяемых данных (количество фишек, например)
- проверяешь все поля на типы данных и ОЧЕНЬ ВАЖНО! - на длину передаваемых значений. Не допускается в строковом поле передавать больше, скажем, 20 символов. Это очень сильно ограничивает брутфорс для поиска
коллизии хэша. Количество фишек должно быть целым положительным числом в определённых допустимых пределах (от 0 до 1000, напримр. Чем меньше диапазон, тем лучше)
- делаешь хэш по переданным значениям и сравниваешь его с переданным хэшем от клиента. Если не совпадают - юзер подменил количество монет.
На сервере у тебя должна быть защита от брутфорса: от одного userId, IP-адреса должно приходить не более 1-3 запросов в секунду. Если больше - банить на некоторое время, например, на 1 минуту.
Это то, что касается систем, где данные передаются ОТ пользователя серверу.
В твоём же случае - это просто игра.
И здесь поступают проще.
Всю логику делают на сервере. Юзер кликнул на монету - передаём серверу инфу: click(userId, x,y)
И вот тут включается логика сервера: он смотрит что за юзер кликнул, куда кликнул, как часто, разрешено ли ему это делать... Если всё в порядке, то сервер отправляет клиенту - Ок, вот тебе заработанные 10 монет. Клиент отрисовывает монетки, юзер радуется.
В этом случае полностью исключается подмена юзером количество монет, потому что всё решает сервер. Клиент - это просто терминал для отображения данных и отправки кликов на сервер.