Как заблокировать скомпилированные classы Java для предотвращения декомпиляции?

Как заблокировать скомпилированные classы Java для предотвращения декомпиляции?

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

Многие люди предлагают обфускатор, но они просто переименовывают classы, методы и поля с жесткими для запоминания последовательностями символов, но как насчет чувствительных постоянных значений?

Например, вы разработали компонент шифрования и дешифрования на основе метода шифрования на основе пароля. Теперь в этом случае любой средний Java-человек может использовать JAD для декомпиляции файла classа и легко получить значение пароля (определенное как постоянное), а также соль и, в свою очередь, может расшифровать данные, написав небольшую независимую программу!

Или должны ли такие чувствительные компоненты быть построены в собственном коде (например, VC ++) и вызвать их через JNI ?

Некоторые из более совершенных obfuscators Java-байт-кода делают гораздо больше, чем просто манипулирование именами. Например, Zelix KlassMaster может также скремблировать stream кода таким образом, что это очень сложно отслеживать и работает как отличный оптимизатор кода …

Также многие из обфускаторов также могут скремблировать ваши строковые константы и удалить неиспользуемый код.

Другое возможное решение (не обязательно исключая обфускацию) заключается в использовании зашифрованных файлов JAR и пользовательского загрузчика classов, который выполняет дешифрование (предпочтительно с использованием собственной библиотеки времени исполнения).

В-третьих (и, возможно, самая сильная защита) следует использовать собственные компиляторы, например, GCC или Excelsior JET , например, которые скомпилируют ваш Java-код непосредственно в родной двоичный файл платформы.

В любом случае вы должны помнить, что, как говорится в эстонской «Замки для животных». Это означает, что каждый бит кода доступен (загружен в память) во время выполнения и имеет достаточный навык, определение и мотивацию, люди могут и будут декомпилировать, расшифровывать и взламывать ваш код … Ваша задача – сделать процесс неудобным, как вы можете и до сих пор держать дело работать …

Пока они имеют доступ как к зашифрованным данным, так и к программному обеспечению, которое его расшифровывает, в принципе вы не можете полностью защитить это. Способы решения этой проблемы прежде всего заключались в использовании внешней формы черного ящика для обработки шифрования / дешифрования, таких как ключи, удаленные серверы аутентификации и т. Д. Но даже тогда, учитывая, что пользователь имеет полный доступ к своей собственной системе, это только делает вещи трудно, а не невозможно – если вы не можете связать свой продукт напрямую с функциональностью, хранящейся в «черном ящике», как, скажем, на онлайн-игровых серверах.

Отказ от ответственности: я не эксперт по безопасности.

Это звучит как плохая идея: вы позволяете кому-то шифровать материал с помощью «скрытого» ключа, который вы ему дадите. Я не думаю, что это можно сделать безопасным.

Возможно, асимметричные клавиши могут работать:

  • развертывать зашифрованную лицензию с открытым ключом для дешифрования
  • позволить клиенту создать новую лицензию и отправить ее вам для шифрования
  • отправьте новую лицензию клиенту.

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

Вы можете сохранить отдельную пару открытого / закрытого ключа для каждого клиента, чтобы убедиться, что вы действительно получаете материал от нужного клиента – теперь вы отвечаете за ключи …

Независимо от того, что вы делаете, его можно «декомпилировать». Черт, вы можете просто разобрать его. Или посмотрите на дамп памяти, чтобы найти свои константы. Видите ли, компьютер должен знать их, поэтому ваш код тоже понадобится.

Что делать с этим?

Старайтесь не отправлять ключ в виде жесткокодированной константы в своем коде: сохраняйте его как настройку для каждого пользователя. Заставьте пользователя отвечать за этот ключ.

Взгляните на статью JavaWorld: Cracking шифрование байтового кода Java от Владимира Рубцова. Это объясняет, почему шифрование файлов classов в основном бессмысленно.

@jatanp: или еще лучше, они могут декомпилировать, удалить лицензионный код и перекомпилировать. С Java я действительно не думаю, что есть правильное, надежное решение этой проблемы. Даже злой маленький ключ мог помешать этому с Java.

Меня беспокоят мои собственные бизнес-менеджеры, и я думаю слишком много. Но опять же, мы продаем наше заявление в крупных корпорациях, которые склонны соблюдать условия лицензирования – как правило, это безопасная среда благодаря счетчикам бонусов и юристам. Акт декомпиляции может быть незаконным, если ваша лицензия написана правильно.

Итак, я должен спросить, действительно ли вам нужна защита, например, вы ищете свое приложение? Как выглядит ваша клиентская база? (Корпорации? Или подростковые массы геймеров, где это будет больше проблемой?)

Я не думаю, что существует эффективный метод оффлайнового антипиратства. В индустрии видеоигр пытались найти, что много раз и их программы всегда были взломаны. Единственное решение состоит в том, что программа должна запускаться в режиме онлайн, подключенная к вашим серверам, чтобы вы могли проверить ключ lincense, и что одновременно имеется только одно активное соединение лицензиата. Так работает World of Warcraft или Diablo . Даже жесткие существуют частные серверы, разработанные для них, чтобы обойти безопасность.

Сказав это, я не считаю, что средние / крупные корпорации используют незаконное скопированное программное обеспечение, потому что стоимость лицензии для них минимальна (возможно, я не знаю, сколько вы собираетесь платить за свою программу) по сравнению с стоимость пробной версии.

Если вы ищете решение для лицензирования, вы можете проверить API TrueLicense . Он основан на использовании асимметричных клавиш. Однако это не означает, что ваше приложение не может быть взломан. Каждое приложение может быть исправлено с достаточным усилием. Что действительно важно, как ответил Сту , выясняя, насколько необходима сильная защита.

Вы можете использовать шифрование байтового кода без страха.

Дело в том, что приведенная выше статья «Cracking Java byte-code encryption» содержит логическую ошибку. Основная претензия к статье перед запуском всех classов должна быть расшифрована и передана ClassLoader.defineClass(...) . Но это не так.

Пропущенное здесь предположение предусматривает, что они работают в аутентичной или стандартной среде Java-времени . Ничто не может обязать защищенное Java-приложение не только запускать эти classы, но даже расшифровывать и передавать их ClassLoader . Другими словами, если вы находитесь в стандартной JRE, вы не можете перехватить defineClass(...) потому что стандартная java не имеет API для этой цели, и если вы используете модифицированную JRE с исправленным ClassLoader или любым другим «хакерским трюком», вы не может этого сделать, потому что защищенное приложение Java не будет работать вообще, и поэтому вам нечего перехватывать. И совершенно неважно, какой «патч-искатель» используется или какой трюк используется хакерами. Эти технические детали – совсем другая история.

В: Если я зашифрую файлы .class и использую специальный загрузчик classов для загрузки и расшифровки их на лету, это предотвратит декомпиляцию?

A: Проблема предотвращения декомпиляции байт-кода Java почти такая же старая, как и сам язык. Несмотря на множество инструментов обфускации, доступных на рынке, новички Java-программистов продолжают думать о новых и умных способах защиты своей интеллектуальной собственности. В этом выпуске Java Q & A я развею некоторые мифы вокруг идеи, часто повторяющейся на дискуссионных форумах.

Крайняя легкость, с которой файлы Java .class могут быть восстановлены в источниках Java, которые очень напоминают оригиналы, имеет много общего с целями проектирования и компиляторами байт-кода Java. Помимо всего прочего, байт-код Java был разработан для компактности, независимости платформы, мобильности сети и простоты анализа с помощью интерпретаторов байтового кода и динамических компиляторов JIT (точно в срок) / HotSpot. Возможно, скомпилированные файлы .class выражают намерение программиста настолько ясно, что их легче анализировать, чем исходный исходный код.

Можно сделать несколько вещей, если не полностью предотвратить декомпиляцию, по крайней мере, сделать это более сложным. Например, в качестве этапа после компиляции вы можете массировать данные .class, чтобы код байта был более сложным для чтения, когда декомпилировался или сложнее декомпилировать в действительный код Java (или оба). Методы, такие как выполнение перегрузки по имени экстремального метода, хорошо работают для первого и манипулируют streamом управления для создания структур управления, которые невозможно представить через синтаксис Java, хорошо работают для последнего. Более успешные коммерческие обфускаторы используют сочетание этих и других методов.

К сожалению, оба подхода должны фактически изменить код, который запускает JVM, и многие пользователи боятся (по праву), что это преобразование может добавить новые ошибки в свои приложения. Кроме того, метод и переименование полей могут вызвать обратные вызовы, чтобы перестать работать. Изменение имен реальных classов и пакетов может привести к поломке нескольких других Java-API (JNDI (интерфейс именования и интерфейса Java), поставщиков URL-адресов и т. Д.). В дополнение к измененным именам, если связь между смещениями байтового кода classа и номерами исходных строк изменена, восстановление исходных следов стека исключений может стать затруднительным.

Тогда есть возможность обфускации исходного исходного кода Java. Но в корне это вызывает аналогичный набор проблем. Шифровать, а не запутывать?

Возможно, вышесказанное заставило вас подумать: «Ну, а что, если вместо манипулирования байтовым кодом я зашифровываю все мои classы после компиляции и расшифровываю их на лету внутри JVM (что может быть сделано с помощью специального загрузчика classов)? Тогда JVM выполняет мой оригинальный байтовый код, и все же нечего декомпилировать или реконструировать, верно? ”

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

Interesting Posts

Определение, если словарь Swift содержит ключ и получает какие-либо его значения

InvalidProgramException / Common Language Runtime обнаружил недопустимую программу

В чем причина «нестатического метода нельзя ссылаться из статического контекста»?

Есть ли команда DOS (cmd.exe из Win7) для извлечения флэш-накопителя?

перерыв петли, если Esc был нажат

Как заставить Windows Explorer использовать подробный просмотр?

Обновить поле в массиве точного элемента в MongoDB

Компилировать и запускать динамический код без генерации EXE?

Как я могу использовать атрибуты проверки данных в C # в контексте nonASP.net?

Как эффективно сфокусироваться на панели поиска google в vimperator?

Медленная загрузка первой страницы на сайт asp.net

Какая хорошая практика для обеспечения полной работоспособности моей батареи ноутбука?

Что такое / usr / bin / [и как его использовать?

Есть ли способ сказать surefire пропустить тесты в определенном пакете?

Как определить существование classа с использованием SFINAE?

Давайте будем гением компьютера.