# Java Code schützen?



## jroxtheworld (1. Apr 2009)

Wie schütze ich meinen Code vor Dekompilieren?

Beispiel:
Ich speichere alle Daten in einer Derby DB, die encrypted auf der Festplatte gepspeichert wird und zusätzlich einen Usernamen und Passwort benötigt. Diese muss ich aber irgendwo im Java Sourcecode hinterlegen.

Mit z.Bsp. DJ Java Decompiler ist das aber für jeden Computer-Dummy einsehbar.

Frage: Wie schütze ich meinen Sourcecode oder zumindest die Teile mit sensitiven Informationen?

Danke


----------



## Wildcard (1. Apr 2009)

Völlig unmöglich. Du kannst es höchstens erschweren, aber jeder der auch nur halbwegs fit ist, kann die Daten auslesen, unabhängig davon ob es sich um Java, C#, C, Assembler, oder sonst was handelt.


----------



## Stefan S. (1. Apr 2009)

jroxtheworld hat gesagt.:


> Wie schütze ich meinen Code vor Dekompilieren?



Gar nicht!

Du kannst einen Obfuscator benutzen. Es gibt kostenlose, wie ProGuard. Der ist ganz brauchbar.

ProGuard

Prinzipiell ist jedes Programm, auch ein inC geschriebenes, dekomplierbar - spätestens auf der Maschinenebene. Man kann den Vorgang durch diverse Mechanismen ein wenig erschweren, mehr nicht.


----------



## jroxtheworld (2. Apr 2009)

Besten Dank für die Info. Ich werde mir das mit dem Obfuscator mal noch genauer anschauen.


----------



## Spacerat (2. Apr 2009)

Ich möchte an dieser Stelle noch mal darauf verweisen. Leider ist das Archiv, auf welches ich dort verweise beim letzten Foren-Umzug wohl untergegangen. Das kann man aber einem noch zu kommen lassen.
<OT>BTW.: Ich hab' da einen "toten" Link entdeckt. Und zwar, wenn man "Schutz vor Decompile" als Suchbegriffe verwendet, wird einem das Thema mit "Seriennummern" angezeigt, in welchem ich auch nach "Schutz vor Decompilierung" verlinkt habe. Dieser Link ist jedoch tot.</OT>


----------



## jroxtheworld (2. Apr 2009)

Danke auch für den Link, zeigt auch schön die Nachteile auf. Prinzipiell handelt es sich dabei ja eigentlich immer darum, dass der Quellcode und dessen Abläufe und evt. Algorithmen geschützt werden sollen.

Mein Problem besteht momentab aber mehr darin, dass ich einzelne Werte in meinem Quellcode schützen möchte, die nich 'ofuscated' werden.
- Benutzernamen und Passwörter für DB / FTP etc.

Wie würdet ihr hier vorgehen?


----------



## tfa (2. Apr 2009)

Sowas kann man grundsätzlich nicht schützen. Passwörter auf dem Client sind nur vom Benutzer einzugeben. In Server-Programmen kann man Passwörter in Config-Dateien o.ä. speichern, aber da kommt von Außen ja auch niemand ran.


----------



## Stefan S. (2. Apr 2009)

jroxtheworld hat gesagt.:


> Danke auch für den Link, zeigt auch schön die Nachteile auf. Prinzipiell handelt es sich dabei ja eigentlich immer darum, dass der Quellcode und dessen Abläufe und evt. Algorithmen geschützt werden sollen.
> 
> Mein Problem besteht momentab aber mehr darin, dass ich einzelne Werte in meinem Quellcode schützen möchte, die nich 'ofuscated' werden.
> - Benutzernamen und Passwörter für DB / FTP etc.
> ...



Java Programme sind noch deutlich angenehmer zu dekompilieren, als Sprachen, die direkt in Maschinencode übersetzt werden, weil eine ganze Menge Metainformationen erhalten bleiben. Bei einem C Programm erhält man immerhin ein hochoptimiertes CPU Listing, welches nur von erfahrenen Assembler Programmierern gelesen werden kann.

Du kannst keine offenen Daten im Quellcode schützen. Du musst diese Daten in jedem Fall verschlüsselt ablegen, z.B. mit AES drüberbügeln.

Die Entschlüsselung muss über eine Benutzereingabe erfolgen, also über einen Textstring der nicht im Quellcode steht. Alles andere ist letztlich knackbar. Im Extremfall dekompiliert der Benutzer nämlich überhaupt nichts, er macht einen Memorydump des laufenden Prozesses und spätestens dort steht das Passwort im Klartext.


----------



## jroxtheworld (2. Apr 2009)

Stefan S. hat gesagt.:


> Du kannst keine offenen Daten im Quellcode schützen. Du musst diese Daten in jedem Fall verschlüsselt ablegen, z.B. mit AES drüberbügeln.
> 
> Die Entschlüsselung muss über eine Benutzereingabe erfolgen, also über einen Textstring der nicht im Quellcode steht. Alles andere ist letztlich knackbar. Im Extremfall dekompiliert der Benutzer nämlich überhaupt nichts, er macht einen Memorydump des laufenden Prozesses und spätestens dort steht das Passwort im Klartext.



Die Daten zu verschlüsseln bringt mir ja eigentlich auch nichts, da sie ja innerhalb vom Programm wiederum entschlüsselt werden müssen, damit z.Bsp. ein FTP mit Passwort angesprochen werden kann. Ein Teufelskreis das ganze... der Benutzer soll das Passwort ja eben nicht kennen, weshalb ich es irgendwo hinterlegen muss.


----------



## jroxtheworld (2. Apr 2009)

Ich habe zu dem Thema noch einen interessanten Artikel gefunden:

*First Case: User is authorized to know the database login credentials*

In this case, the solution I mentioned above will work. The Java Preference class will stored the username and password in plain text, but the preferences file will only be readable by the authorized user. The user can simply open the preferences XML file and read the login credentials, but that is not a security risk because the user knew the credentials to begin with.

*Second Case: Trying to hide login credentials from the user*

This is the more complicated case: the user should not know the login credentials but still needs access to the database. In this case, the user running the application has direct access to the database, which means the program needs to know the login credentials ahead of time. The solution I mentioned above is not appropriate for this case. You can store the database login credentials in a preferences file, but he user will be able to read that file, since they will be the owner. In fact, there is really no good way to use this case in a secure way. 

(Das wäre also mein Case, der nicht weiter schützbar ist)

How can I protect MySQL username and password from decompiling? - Stack Overflow


----------



## maki (2. Apr 2009)

Brauchst so etwas wie einen Server, der kann Usernamen & Passwort halten.

Ansonsten wars das.


----------



## jroxtheworld (2. Apr 2009)

Falls z.Bsp. der DB-Zugang auf dem Server gemacht wird, hat der Client zwar keine Chance das Klartext-Passwort zu erfahren, aber er weiss ja aus dem Client-Code wie mit dem Server kommuniziert werden kann, und kann sich so aus seinem eigenen Programm Zugriff auf die DB verschaffen ...oder vergesse ich da etwas?


----------



## tfa (2. Apr 2009)

Hoffentlich kann er das nicht. Der Server versorgt den Client mit Daten aus der DB. Er liefert natürlich nur die, die der Client sehen darf. Dazu muss sich der Anwender am Server anmelden, mit UserID und Passwort (was natürlich ein anderes ist, als der DB-Zugang).


----------



## jroxtheworld (2. Apr 2009)

Aber im Client-Code werden vielleicht auch Methoden aufgerufen, die Daten in die DB schreiben. Jetzt kann ich diese Methode aufrufen und dem Programm einen anderen Wert mitgeben, der zwar valide ist aber nicht dem effektiven Wert entspricht.

Bsp.: Das Programm speichert die Anzahl korrekt gelöster Aufgaben in der DB. Ich habe zwar nur 2 Antworten korrekt gelöst, aber kann der Methode auch einfach 5 korrekte übergeben.

Ich glaube ich gehe langsam zu weit


----------



## maki (2. Apr 2009)

Du müsstest zwischen Serveraufgaben und CLientaufgaben unterscheiden.

Um bei deinem Beispiel zu bleiben:
Der Client speichert nix in die DB, das macht der Server.
Der Client entscheidet auch nicht wieviele Aufgaben gelöst wurden, das macht der Server.


----------



## tfa (2. Apr 2009)

Vereinfacht gesagt dient der Client nur dazu, vom Server geladene Daten auf dem Bildschirm anzuzeigen und Benutzereingaben an den Server zu schicken. Sozusagen ein Bildschirm-/Maus-/Tastatur-Treiber. Das Denken findet auf dem Server statt. (Der Client darf natürlich auch ein bisschen vorausschauend mitdenken, aber alles muss auf Serverseite nochmal überprüft werden.)


----------



## jroxtheworld (2. Apr 2009)

Okay, eine ganz klare Trennung wäre also von Nöten. Das geht natürlich in meinem Fall leider nicht. Also werde ich wohl oder übel einfach schauen müssen, dass die Daten nicht mit einmal dekompilieren schon sichtbar sind.

Danke euch für den Input!


----------



## maki (2. Apr 2009)

Den Aufwand kannst du dir imho sparen, bringt nicht wirklich etwas.

Beispiel:
Ich dekompiliere deine App, dann lasse ich sie im Debugger laufen mit einem Breakpoint an der Stelle, an der die DB Verbindung gemacht wird und lese Usernamen und Passwort aus.
Egal wieviel Aufwand du reinsteckst, das geht immer.


----------



## Spacerat (2. Apr 2009)

@TS: Weis' jetzt nicht, ob du dir meinen Link von oben schon mal angesehen hast. Ich habe dort mit einfachen Mitteln (XOR) den ByteCode einer Klasse verschlüsselt, und damit vor "decompile" geschützt. Erfolgreicher dürfte es alledings mit RSA sein. Denkbar wäre dann auch noch, das die durch den dort verwendeten ClassLoader entschlüsselte Klasse eine Prüfsumme des ClassLoaders speichert und bei ihrer Initialisierung diese mit einer "frisch" erstellten vergleicht. So kann sie unter Umständen feststellen, ob der CL bereits dekompiliert und anschliessend wieder kompiliert wurde. (ReverseEngineering == Ikea-Spiel->"Endecke die Möglichkeiten")


----------



## Wildcard (2. Apr 2009)

Ja, security through obscurity war ja schon immer ein sinnvoller Ansatz :autsch:


----------

