Wie sperre ich kompilierte Java-Klassen, um eine Dekompilierung zu verhindern?
Ich weiß, dass dieses Thema im Internet sehr gut diskutiert werden muss, aber ich konnte nach dem Verweisen zu keinem Ergebnis kommen.
Viele Leute schlagen Obfuscator vor, aber sie benennen nur Klassen, Methoden und Felder mit schwer zu merkenden Zeichenfolgen um, aber was ist mit sensiblen konstanten Werten?
Beispielsweise haben Sie die Verschlüsselungs- und Entschlüsselungskomponente basierend auf einer kennwortbasierten Verschlüsselungstechnik entwickelt. In diesem Fall kann jede durchschnittliche Java-Person JAD verwenden, um die Klassendatei zu dekompilieren und den Kennwortwert (definiert als Konstante) sowie Salt einfach abzurufen. Die Daten können wiederum entschlüsselt werden, indem ein kleines unabhängiges Programm geschrieben wird!
Oder sollten solche sensiblen Komponenten in nativem Code (z. B. VC ++) erstellt und über JNI aufgerufen werden ?
quelle
Antworten:
Einige der fortschrittlicheren Java-Bytecode-Verschleierer leisten viel mehr als nur das Mangeln von Klassennamen. Zelix KlassMaster zum Beispiel kann Ihren Code-Fluss auch so verschlüsseln, dass es wirklich schwierig ist, ihm zu folgen, und als hervorragender Code-Optimierer fungiert ...
Viele der Verschleierer sind auch in der Lage, Ihre Zeichenfolgenkonstanten zu verschlüsseln und nicht verwendeten Code zu entfernen.
Eine andere mögliche Lösung (die die Verschleierung nicht unbedingt ausschließt) besteht darin, verschlüsselte JAR-Dateien und einen benutzerdefinierten Klassenladeprogramm zu verwenden, das die Entschlüsselung durchführt (vorzugsweise unter Verwendung der nativen Laufzeitbibliothek).
Drittens (und möglicherweise mit dem stärksten Schutz) sollten native Compiler wie GCC oder Excelsior JET verwendet werden, die Ihren Java-Code direkt in eine plattformspezifische native Binärdatei kompilieren.
Auf jeden Fall muss man sich daran erinnern, wie das Sprichwort auf Estnisch lautet: "Schlösser sind für Tiere". Das bedeutet, dass jedes Codebit zur Laufzeit verfügbar ist (in den Speicher geladen wird) und bei ausreichender Geschicklichkeit, Entschlossenheit und Motivation den Code dekompilieren, entschlüsseln und hacken kann und wird. Ihre Aufgabe besteht einfach darin, den Prozess so unangenehm wie möglich zu gestalten Sie können und halten das Ding am Laufen ...
quelle
Solange sie Zugriff auf die verschlüsselten Daten und die Software haben, die sie entschlüsselt, können Sie dies grundsätzlich nicht vollständig sicher machen. Dies wurde bereits gelöst, indem eine externe Blackbox für die Verschlüsselung / Entschlüsselung verwendet wurde, z. B. Dongles, Remote-Authentifizierungsserver usw. Aber selbst dann, wenn der Benutzer vollen Zugriff auf sein eigenes System hat, macht dies nur Dinge schwierig, nicht unmöglich - es sei denn, Sie können Ihr Produkt direkt an die in der "Black Box" gespeicherte Funktionalität binden, wie beispielsweise Online-Gaming-Server.
quelle
Haftungsausschluss: Ich bin kein Sicherheitsexperte.
Das klingt nach einer schlechten Idee: Sie lassen jemanden Sachen mit einem 'versteckten' Schlüssel verschlüsseln, den Sie ihm geben. Ich denke nicht, dass dies sicher gemacht werden kann.
Vielleicht könnten asymmetrische Schlüssel funktionieren:
Ich bin nicht sicher, aber ich glaube, der Client kann den Lizenzschlüssel tatsächlich mit dem öffentlichen Schlüssel verschlüsseln, den Sie ihm gegeben haben. Sie können es dann mit Ihrem privaten Schlüssel entschlüsseln und ebenfalls neu verschlüsseln.
Sie können ein separates öffentliches / privates Schlüsselpaar pro Kunde führen, um sicherzustellen, dass Sie tatsächlich Informationen vom richtigen Kunden erhalten - jetzt sind Sie für die Schlüssel verantwortlich ...
quelle
Egal was Sie tun, es kann "dekompiliert" werden. Du kannst es einfach zerlegen. Oder schauen Sie sich einen Speicherauszug an, um Ihre Konstanten zu finden. Sie sehen, der Computer muss sie kennen, also muss auch Ihr Code.
Was tun?
Versuchen Sie, den Schlüssel nicht als fest codierte Konstante in Ihrem Code zu versenden: Behalten Sie ihn als Benutzereinstellung bei. Machen Sie den Benutzer für die Pflege dieses Schlüssels verantwortlich.
quelle
@jatanp: oder noch besser, sie können dekompilieren, den Lizenzcode entfernen und neu kompilieren. Ich glaube nicht, dass es mit Java eine richtige, hackfeste Lösung für dieses Problem gibt. Nicht einmal ein böser kleiner Dongle konnte dies mit Java verhindern.
Meine eigenen Geschäftsleiter machen sich darüber Sorgen, und ich denke zu viel. Andererseits verkaufen wir unsere Anwendung an große Unternehmen, die dazu neigen, die Lizenzbedingungen einzuhalten - im Allgemeinen eine sichere Umgebung dank der Bohnenzähler und Anwälte. Das Dekompilieren selbst kann illegal sein, wenn Ihre Lizenz korrekt geschrieben ist.
Also, ich muss fragen, brauchen Sie wirklich einen gehärteten Schutz, wie Sie ihn für Ihre Anwendung suchen? Wie sieht Ihr Kundenstamm aus? (Unternehmen? Oder die jugendlichen Spielermassen, wo dies eher ein Problem wäre?)
quelle
Wenn Sie nach einer Lizenzierungslösung suchen, können Sie die TrueLicense-API überprüfen . Es basiert auf der Verwendung asymmetrischer Schlüssel. Dies bedeutet jedoch nicht, dass Ihre Anwendung nicht geknackt werden kann. Jede Anwendung kann mit genügend Aufwand geknackt werden. Was wirklich wichtig ist, ist, wie Stu antwortete , herauszufinden, wie stark Sie Schutz brauchen.
quelle
Ich glaube nicht, dass es eine effektive Offline-Antipiraterie-Methode gibt. Die Videospielbranche hat schon oft versucht, dies herauszufinden, und ihre Programme wurden immer geknackt. Die einzige Lösung besteht darin, dass das Programm online in Verbindung mit Ihren Servern ausgeführt werden muss, damit Sie den Weihrauchschlüssel überprüfen können und dass jeweils nur eine aktive Verbindung durch den Lizenznehmer besteht. So funktioniert World of Warcraft oder Diablo . Selbst wenn es schwierig ist, werden private Server entwickelt, um die Sicherheit zu umgehen.
Trotzdem glaube ich nicht, dass mittelständische / große Unternehmen illegale kopierte Software verwenden, da die Lizenzkosten für sie minimal sind (vielleicht weiß ich nicht, wie viel Sie für Ihr Programm verlangen müssen) die Kosten für eine Testversion.
quelle
Sie können die Bytecode-Verschlüsselung ohne Angst verwenden.
Tatsache ist, dass das oben zitierte Papier „Cracking Java Byte-Code-Verschlüsselung“ einen logischen Irrtum enthält. Der Hauptanspruch des Papiers besteht darin, dass vor dem Ausführen alle Klassen entschlüsselt und an die
ClassLoader.defineClass(...)
Methode übergeben werden müssen . Aber das ist nicht wahr.Die hier übersehene Annahme wird vorausgesetzt, dass sie in einer authentischen oder Standard-Java-Laufzeitumgebung ausgeführt werden . Nichts kann die geschützte Java-App dazu verpflichten, diese Klassen nicht nur zu starten, sondern sogar zu entschlüsseln und an sie weiterzugeben
ClassLoader
. Mit anderen Worten, wenn Sie sich in einer Standard-JRE befinden, können Sie diedefineClass(...)
Methode nicht abfangen , da die Standard-Java zu diesem Zweck keine API hat. Wenn Sie eine modifizierte JRE mit gepatchtenClassLoader
oder anderen „Hacker-Tricks“ verwenden, können Sie dies nicht tun, da sie geschützt sind Die Java-App funktioniert überhaupt nicht und Sie müssen daher nichts abfangen. Und es spielt absolut keine Rolle, welcher „Patch Finder“ verwendet wird oder welcher Trick von Hackern verwendet wird. Diese technischen Details sind eine ganz andere Geschichte.quelle
F: Wenn ich meine .class-Dateien verschlüssele und sie mit einem benutzerdefinierten Klassenladeprogramm lade und entschlüssele, verhindert dies die Dekompilierung?
A: Das Problem, die Dekompilierung von Java-Bytecode zu verhindern, ist fast so alt wie die Sprache selbst. Trotz einer Reihe von auf dem Markt erhältlichen Verschleierungstools denken unerfahrene Java-Programmierer weiterhin über neue und clevere Möglichkeiten zum Schutz ihres geistigen Eigentums nach. In diesem Java Q & A-Teil zerstreue ich einige Mythen über eine Idee, die häufig in Diskussionsforen aufgearbeitet wird.
Die extreme Leichtigkeit, mit der Java-Klassendateien in Java-Quellen rekonstruiert werden können, die den Originalen sehr ähnlich sind, hat viel mit den Zielen und Kompromissen beim Entwurf von Java-Bytecode zu tun. Java-Bytecode wurde unter anderem für Kompaktheit, Plattformunabhängigkeit, Netzwerkmobilität und einfache Analyse durch Bytecode-Interpreter und dynamische JIT- (Just-in-Time) / HotSpot-Compiler entwickelt. Die kompilierten .class-Dateien drücken wohl die Absicht des Programmierers so deutlich aus, dass sie leichter zu analysieren sind als der ursprüngliche Quellcode.
Es können verschiedene Dinge getan werden, um die Dekompilierung nicht vollständig zu verhindern, zumindest um sie schwieriger zu machen. Als Schritt nach der Kompilierung können Sie beispielsweise die .class-Daten massieren, um den Bytecode beim Dekompilieren entweder schwerer zu lesen oder in gültigen Java-Code (oder beides) zu dekompilieren. Techniken wie das Überladen extremer Methodennamen funktionieren bei ersteren gut, und das Manipulieren des Kontrollflusses zum Erstellen von Kontrollstrukturen, die nicht durch Java-Syntax dargestellt werden können, funktionieren bei letzteren gut. Die erfolgreicheren kommerziellen Verschleierer verwenden eine Mischung dieser und anderer Techniken.
Leider müssen beide Ansätze tatsächlich den Code ändern, den die JVM ausführen wird, und viele Benutzer befürchten (zu Recht), dass diese Umwandlung ihren Anwendungen neue Fehler hinzufügen könnte. Darüber hinaus kann das Umbenennen von Methoden und Feldern dazu führen, dass Reflection-Aufrufe nicht mehr funktionieren. Das Ändern der tatsächlichen Klassen- und Paketnamen kann mehrere andere Java-APIs (JNDI (Java Naming and Directory Interface), URL-Anbieter usw.) beschädigen. Zusätzlich zu geänderten Namen kann es schwierig werden, die ursprünglichen Ausnahmestapelspuren wiederherzustellen, wenn die Zuordnung zwischen Klassenbytecode-Offsets und Quellzeilennummern geändert wird.
Dann besteht die Möglichkeit, den ursprünglichen Java-Quellcode zu verschleiern. Grundsätzlich verursacht dies jedoch ähnliche Probleme. Verschlüsseln, nicht verschleiern?
Vielleicht hat Sie das oben Gesagte zum Nachdenken gebracht: "Nun, was ist, wenn ich anstelle der Manipulation des Bytecodes alle meine Klassen nach dem Kompilieren verschlüssele und sie im laufenden Betrieb in der JVM entschlüssele (was mit einem benutzerdefinierten Klassenladeprogramm möglich ist)? Dann führt die JVM meinen aus Original-Byte-Code und doch gibt es nichts zu dekompilieren oder zurückzuentwickeln, oder? "
Leider würden Sie sich irren, sowohl wenn Sie denken, dass Sie als erster auf diese Idee gekommen sind, als auch wenn Sie denken, dass sie tatsächlich funktioniert. Und der Grund hat nichts mit der Stärke Ihres Verschlüsselungsschemas zu tun.
quelle