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

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

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

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

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

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

Ответ 1

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

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

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

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

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

Ответ 2

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

Ответ 3

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

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

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

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

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

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

Ответ 4

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

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

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

Ответ 6

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

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

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

Ответ 7

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

Ответ 8

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

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

Ответ 9

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

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

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

Ответ 10

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

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

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

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

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

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

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

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