Первое правило безопасности приложения. Любая машина, к которой злоумышленник получает неограниченный физический или электронный доступ, теперь принадлежит вашему злоумышленнику, независимо от того, где он находится и сколько вы заплатили за него.
Второе правило безопасности приложения. Любое программное обеспечение, которое выходит за физические границы, в которые злоумышленник не может проникнуть, теперь принадлежит вашему злоумышленнику, независимо от того, сколько времени вы потратили на его кодирование.
Третье правило: любая информация, выходящая за те же физические границы, в которую злоумышленник не может проникнуть, теперь принадлежит вашему злоумышленнику, независимо от того, насколько она ценна для вас.
Основы безопасности информационных технологий основаны на этих трех фундаментальных принципах; единственный действительно безопасный компьютер - это тот, который заперт в сейфе внутри клетки Фаррадея, внутри стальной клетки. Есть компьютеры, которые проводят большую часть своего срока службы именно в этом состоянии; один раз в год (или реже) они генерируют закрытые ключи для доверенных корневых центров сертификации (перед множеством свидетелей с камерами, фиксирующими каждый дюйм помещения, в котором они находятся).
В настоящее время большинство компьютеров не используются в этих типах сред; они физически находятся на улице, подключены к Интернету по беспроводному радиоканалу. Короче говоря, они уязвимы, как и их программное обеспечение. Поэтому им нельзя доверять. Есть определенные вещи, которые компьютеры и их программное обеспечение должны знать или делать для того, чтобы быть полезными, но необходимо позаботиться о том, чтобы они никогда не знали или не делали достаточно, чтобы нанести ущерб (по крайней мере, не наносить непоправимый ущерб за пределы этой единственной машины). ).
Вы уже знали все это; Вот почему вы пытаетесь защитить код вашего приложения. Но в этом заключается первая проблема; инструменты запутывания могут сделать код беспорядком для человека, чтобы попытаться копаться, но программа все еще должна работать; это означает, что фактический логический поток приложения и данные, которые оно использует, не подвержены запутыванию. Учитывая немного упорства, злоумышленник может просто не запутывать код, и это даже не требуется в некоторых случаях, когда то, на что он смотрит, не может быть ничем иным, кроме того, что он ищет.
Вместо этого вы должны пытаться гарантировать, что злоумышленник не сможет ничего сделать с вашим кодом, независимо от того, насколько легко ему получить его четкую копию. Это означает, что нет жестко закодированных секретов, потому что эти секреты не являются секретными, как только код покидает здание, в котором вы его разработали.
Эти значения ключей, которые вы жестко запрограммировали, должны быть полностью удалены из исходного кода приложения. Вместо этого они должны быть в одном из трех мест; энергозависимая память на устройстве, которую злоумышленнику труднее (но все же не невозможно) получить автономную копию; постоянно на кластере серверов, к которому вы управляете доступом железным кулаком; или во втором хранилище данных, не связанном с вашим устройством или серверами, например, физической картой или в памяти вашего пользователя (это означает, что он в конечном итоге будет находиться в энергозависимой памяти, но это не должно длиться долго).
Рассмотрим следующую схему. Пользователь вводит свои учетные данные для приложения из памяти в устройство. К сожалению, вы должны верить, что устройство пользователя еще не взломано кейлоггером или трояном; лучшее, что вы можете сделать в этом отношении, - это реализовать многофакторную защиту, запоминая трудно подделываемую информацию об устройствах, которые использовал пользователь (MAC / IP, IMEI и т. д.), и предоставив по крайней мере один дополнительный канал с помощью какую попытку входа в систему на незнакомом устройстве можно проверить.
После ввода учетных данных клиентская программа обфускацирует их (используя безопасный хэш), а учетные данные в виде простого текста отбрасывают; они послужили своей цели. Обфусцированные учетные данные отправляются по защищенному каналу на сервер, прошедший проверку подлинности сертификата, который снова их хеширует для получения данных, используемых для проверки правильности входа в систему. Таким образом, клиент никогда не знает, что на самом деле сравнивается со значением базы данных, сервер приложений никогда не знает учетные данные в виде простого текста, которые он получает для проверки, сервер данных никогда не знает, как создаются данные, которые он хранит для проверки, и человек в середина видит только тарабарщину, даже если безопасный канал был взломан.
После проверки сервер передает токен по каналу. Токен полезен только в безопасном сеансе, состоит из случайного шума или зашифрованной (и, следовательно, проверяемой) копии идентификаторов сеанса, и клиентское приложение должно отправить этот токен по тому же каналу на сервер как часть любого запроса. сделать что-то. Клиентское приложение будет делать это много раз, потому что оно не может делать ничего, включая деньги, конфиденциальные данные или что-либо еще, что может повредить само по себе; вместо этого он должен попросить сервер выполнить эту задачу. Клиентское приложение никогда не будет записывать какую-либо конфиденциальную информацию в постоянную память на самом устройстве, по крайней мере, не в виде простого текста; клиент может запросить у сервера по безопасному каналу симметричный ключ для шифрования любых локальных данных, которые сервер запомнит; в более позднем сеансе клиент может запросить у сервера тот же ключ для расшифровки данных для использования в энергозависимой памяти. Эти данные тоже не будут единственной копией; все, что хранит клиент, также должно быть в той или иной форме передано на сервер.
Очевидно, что это делает ваше приложение сильно зависимым от доступа в Интернет; клиентское устройство не может выполнять какие-либо из своих основных функций без надлежащего подключения и аутентификации на сервере. Не отличается от Facebook, правда.
Теперь компьютер, который хочет злоумышленник, - это ваш сервер, потому что именно он, а не клиентское приложение / устройство - это то, что может принести ему деньги или причинить другим людям боль от его удовольствия. Это нормально; вы получаете гораздо больше денег, затрачивая деньги и усилия на защиту сервера, чем на защиту всех клиентов. Сервер может находиться за всеми видами брандмауэров и другой электронной безопасности, а также может быть физически защищен за стальным, бетонным, доступом с помощью карточек / штырьков и 24-часовым видеонаблюдением. Ваш злоумышленник должен быть действительно изощренным, чтобы получить любой доступ к серверу напрямую, и вы должны (должны) знать об этом немедленно.
Лучшее, что может сделать злоумышленник, - это украсть телефон и учетные данные пользователя и войти на сервер с ограниченными правами клиента. Если это произойдет, как если бы вы потеряли кредитную карту, законный пользователь должен получить указание позвонить по номеру 800 (желательно, чтобы его было легко запомнить, а не на оборотной стороне карты, которую он носил бы в своем кошельке, кошельке или портфеле, который может быть украденный вместе с мобильным устройством) с любого телефона, к которому у них есть доступ, который напрямую связывает их с вашей службой поддержки клиентов. Они заявляют, что их телефон был украден, предоставляют некоторый базовый уникальный идентификатор, а учетная запись заблокирована, все транзакции, которые злоумышленник, возможно, смог обработать, откатываются, и злоумышленник возвращается к исходной точке.