Information Security
C#
Unity3D
Comments 34
0
К сожалению, еще не изучал механизм покупок в AppStore. Поэтому написал только про Google Play.
0
Нет, на сколько я знаю все актуальные программы для подделки IAP на iOS умеют так же подделывать сервер верификации. Для защиты от подобных программ надо передавать и верифицировать покупки на сервере. При чем некоторые программы для взлома могут отдавать валидные ключи верификации, просто, например, от другого приложения. Поэтому сервер должен полностью проверять ответ от эпла.
0
З.Ы. Да и не ключ это таки совсем, а вектор инициализации. Если придираться к терминологии.
По сути — таже соль только для алгоритма шифрования.
+1
IV оставлять константой не правильно. Он нужен для того что бы одинаковые данные зашифрованные тем же ключем выглядели по разному. А у вас тут уязвимость.
0
Согласен. По гадлайнам нужно каждый раз при шифровании генерировать случайный IV и хранить его вместе с зашифрованным сообщением. Допишу в TODO.
0
Вообще говоря нет, это если Mode == CipherMode.ECB (самый небезопасный), то одинаковые последовательные блоки шифровались бы одинаковыми блоками. А при других значениях будет по-другому.
UFO landed and left these words here
0
Среди моих знакомых Unity-программистов большинство пишет на C#. Насчет JSON — если использовать реализацию SimpleJSON, то все так же просто, как и в php, foreach тоже будет работать. Дело привычки.
UFO landed and left these words here
0
private const string VIKey = "~6YUi0Sv5@|{aOZO"

В векторе инициализации мало смысла, если он хранится в открытом виде и может быть извлечен атакующим.

new RijndaelManaged { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros }

Не стоит CBC. Из «коробочных» лучше взять CFB или OFB, а то здесь padding oracle на ровном месте получится (даже, если CryptographicException из cryptoStream.Read() будет ловиться где-то выше, то по-прежнему будет возможность получить time-based oracle). А то, при такой реализации, получается, что есть возможность полностью расшифровать значение всего сейва без ключа и зашифровать в него произвольный текст, за исключением его первого блока.
0
VIKey хранится в приложении. Его, конечно, можно дополнительно закрыть. Но считаем, что если взломщик дошел до анализа и модификации исполняемого кода, то тут уже ничто не поможет. Халявные плюшки ему за труды)
-1
В векторе инициализации мало смысла, если он хранится в открытом виде и может быть извлечен атакующим.

Бред.
Вы бы почитали сперва зачем этот вектор и как влияет на шифротекст. Можете здесь.
-2
В режиме CBC, при атаке на оракул дополнения, вектор инициализации влияет на возможность атакующего расшифровать первый (и только первый) блок сообщения. Если атакующему известен IV, то он может расшифровать с помощью оракула все блоки сообщения. Если нет, то все, за исключением первого. Можете почитать об этом прямо здесь. А можете взять сплоит github.com/kochetkov/Yapoet и убедиться в этом сами. Тестовое уязвимое приложение, на котором можно поэкспериментировать, там есть.
-1
Я всё это прекрасно знаю.
Тут проблема в выборе режима алгоритма для конкретной задачи а не в том что IV открыт.
Не нужно людей вводить в заблуждение.
-2
Проблема уязвимости к атаке — в выбранном режиме. Проблема подверженности ей в полной мере — в открытости IV. Никаких заблуждений.

Что же касается вопроса открытости IV безотносительно конкретной атаки, то он должен быть либо случайным и непредсказуемым и тогда может быть открытым (как и упомянуто по вашей ссылке), вплоть до передачи его в качестве первого блока сообщения. В любом другом случае, его стоит скрыть (что является security by obscurity, плохо — да, но все же имеет хоть какой-то смысл, по сравнению с открытым константным IV).
0
Спасибо за статью! Часть про проверку подписи маркета многим пригодится.
Внутри-игровые покупки вообще ставят разработчика в неудобное положение — с одной стороны, все, что связано с деньгами, однозначно нужно проверять на сервере. С другой — что, если это однопользовательская игра и сервера просто нет?
Пока все выгладит так, будто любая игра, которая хранит данные о купленом контенте на клиенте, может оказаться где-нибудь на 4pda, в виде apk файла с фичей «энергия бесконечна, все премиумные шмотки уже куплены». Есть подозрение, что тут нужно уже не просто «прятать» переменные, но закладывать дополнительные проверки в игровой механике.
Если бы кто-то поделился опытом разруливания такой ситуации — было бы очень здорово. Очень интересный момент.
0
Нет сервера, проверяйте на клиенте, там всего-то надо пару запросов отправить.
0
Спасибо большое. Как раз пришло время реализовывать защиту данных в игре.
0
Вкратце — в iOS нет Reflection, т.к. .NET для iOS основана на технологии AOT. При реализации приходится самому переопределять и реализовывать методы для составления и разбора словаря.
0
Вкратце, это не так, потому что AOT без метаданных не работает, сборки всегда включены в готовое приложение и Reflection на iOS функционирует в той или иной мере (а может и на 100%, не проверял полностью).

Если детально, то утверждение «не пользуйтесь XML, у него проблемы в iOS» не корректно, пока жив и работает System.Xml (а появился он 13 лет назад, работает буквально везде на Mono/.Net и отмирать начал лишь сейчас на WinRT/WP в сторону System.Xml.Linq). Вопрос удобства и разбора уже тема отдельная, но всяко лучше строки с сепараторами :)

P.S. По существу статьи как раз комментариев нет и холивар тут разводить не о чем. Просто утверждение уж очень категоричное было.
0
Все-равно не понимаю. На какие проблемы он натолкнется? По ссылке ничего про XML нет, по опыту скажу, что никаких проблем с XML я за последние годы не замечал. Вот с SQLite есть проблемы, но это отдельный раговор.
Если же начинающий пользователь не умеет вообще работать с XML, но отлично оперирует с JSON и AES шифрованием, то я вообще отстал от жизни :)
0
Вот с SQLite есть проблемы, но это отдельный раговор.

Можно по точнее какие проблемы? — уже как полгода перевел действующий проект на хранение данных в Sqlite? проект на ios, android… проблем с Sqlite не обнаружено, использовал Sqlitekit — который базируется на порте Sqlite под C# ( https://code.google.com/archive/p/csharp-sqlite/ ) что позволяет без препятственно использовать Sqlite на (почти любой платформе)… Собственно на ios, android — 100% работает
0
В целом, прошло более двух лет с того сообщения, а проблема была еще на год-полтора раньше. Вполне может быть, что все это уже не актуально
Расскажу кратко о своей ситуации: из-за особенностей дизайна программы, она хранит кучу разных данных и дополнительно таблицу с блобами. В итоге файл .db получается достаточно большой, около 5 мегабайт. При этом размере, и System.Data.SQLite и Mono.Data.Sqlite (оба — объектно-ориентированные интерфейсы к libsqlite3) начинают существенно тормозить и периодически не закрывать транзакции при постоянном пересоздании SqliteConnection. Возможно дело было в таймаутах, многопоточности или чем-то еще, но уже разобраться было почти не возможно. В качестве решения я сделал пул SqliteConnection и принудительную однопоточность, что есть костылем костыльным. В следующих приложениях были не такие размеры, да и меньше работы с базой (кеширование вместо постоянного чтения/записи и т.д.), проблема больше не возникала.

P.S. Подход с встраиванием в свое приложение отдельной реализации Sqlite я не очень поддерживаю. Как минимум, нативная и динамически загружаемая libsqlite3.so (.dylib) может иметь более актуальную версию с правками от разработчиков. Как максимум, прекомпилированная C версия работает быстрее.
+1
Все помнят такую PC программу, как ArtMoney? Она умела искать значения в RAM и за несколько итераций отсеивания позволяла стать миллионером в игре.


  • Если игра сетевая, то главная защита должна быть на сервере, а на клиенте нужно защищать протокол общения с сервером. Деньги у игрока появляются после подтверждения неких действий сервером, а не игрок серверу указывает сколько у него денег.
  • Если игра локальная и юзер облегчит себе игровой процесс, то это его сознательный выбор. Может он хочет таким образом побыстрее выиграть все бонусы и избавиться от игровой зависимости к данной игре ;)
  • Если Вы хотите добиться рабства от игрока, тогда соглашусь… шифруйте все и вся. Заодно юзер будет вынужден прикупить аппарат попроизводительнее.
0
Удобно получается, если методами Encrypt и Decrypt расширить string.
        public static string Encrypt(this string value, string password)
        {
            return Encrypt(Encoding.UTF8.GetBytes(value), password);
        }
Only those users with full accounts are able to leave comments.  , please.