Entwickler-Ecke

Sonstiges (Delphi) - Programm schützen: Bild verschlüsseln


P@u1 - Fr 26.02.10 16:23
Titel: Programm schützen: Bild verschlüsseln
Ich habe mir als Schutz für ein Programm, dass zum Funktionieren ein paar ganz bestimmte Bilder benötigt folgendes überlegt:

Wenn jemand das Programm haben will, dann startet er zu erst eine Anwendung, die seine Computer-ID oder sowas in der Art generiert - sollte eine ID sein, die sich nicht ändert.

Dann schickt er mir die ID z.B. per Email.

Aufgrund dieser ID verschlüssel ich dann die Bilder (ein paar Pixel ändern würde bereits reichen) und generiere aufgrund der Computer-ID einen Entschlüsselungscode, der nur für genau diese Bilder und diese ID funktioniert.

Dann verschicke an ihn das Programm inkl. der verschlüsselten Bilder und dem Entschlüsselungscode.

Das Programm läd sich dann bei jedem Start die Bilder rein und entschlüsselt sie intern.

Jetzt fragt ihr euch: Warum der Umweg über die Bilder?
Ein Schutz ohne Bilder kann soweit ich weiß leicht umgangen werden (z.B. dekompilieren und Abfragen rausnehmen), das geht bei den Bildern nicht, weil ohne diese die Funktion des Programms nutzlos wird.
So soll dann verhindert werden, dass das Programm einfach so weiter gegeben werden kann.

Also ein paar Fragen dazu:

1. Was haltet ihr generell von diesem Vorgehen, könnt ihr euch vll bessere Möglichkeiten denken?
Eine Schwachstelle ist vermutlich, dass man die entschlüsstelten Bilder, die während der Laufzeit im Arbeitsspeicher sind bestimmt irgendwie rauskriegt, aber dieses Risiko ist nicht so schlimm.

2. Welche ID nimmt man dafür am besten und wie wird diese bestimmt?

3. Wie ver-/entschlüssele ich Bilder am besten? (liegen im bmp Format vor)
Hinweis dazu: Soweit ich weiß, muss die Verschlüsselung nicht besonders gut sein, da wenn jemand versucht sie per Bruteforce zu knacken er für jede Möglichkeit erst das Programm starten und die Funktion testen muss.


glotzer - Fr 26.02.10 16:40

zu 2 hätt ich ne idee: schnapp dir die seriennummer vom cpu oder so und verschlüssel die mit md5 das gibt normalerweise schöne ids


P@u1 - Fr 26.02.10 16:47

gut, sowas in der art hatte ich mir gedacht. Ich werd dann mall bischen suchen, wie das geht.
Ihr könnt es aber auch gerne hier reinschreiben, wenn ihrs wisst^^
Hat noch wer was gutes für die anderen Fragen plz?


platzwart - Fr 26.02.10 16:48

Du machst einen riesen Denkfehler! Auch dein Programm ist innerhalb einer Minute dank Decompilierung geknackt. Das Bild und die Funktion zum Entschlüsseln sind vollkommen egal! Man muss im Code nur die Stelle finden, wo die Funktion sagt "JA, Schlüssel/ID/Bild/WasAuchImmer ist OK" und diese Stelle springt man dann einfach immer an...


Xentar - Fr 26.02.10 16:51

MD5 ist keine Verschlüsselung, sondern ein Hashwert. Ginge aber damit.

Versteh ich dich richtig: Dein Programm ist darauf angewiesen, dass die Bilder auf den Pixel korrekt sein müssen?
Rein aus Interesse: Was ist das für ein Programm, bzw. was hat es mit den Bildern auf sich?

Wenn ich das richtig verstehe, wäre es wohl ne Möglichkeit.. wobei solche Hardware IDs immer den Nachteil haben, dass man einen neuen Schlüssel braucht, sobald man seinen Rechner aufrüstet.
Wie wäre es einfach mit einem USB Dongle?


P@u1 - Fr 26.02.10 19:39

user profile iconplatzwart hat folgendes geschrieben Zum zitierten Posting springen:
Du machst einen riesen Denkfehler! Auch dein Programm ist innerhalb einer Minute dank Decompilierung geknackt. Das Bild und die Funktion zum Entschlüsseln sind vollkommen egal! Man muss im Code nur die Stelle finden, wo die Funktion sagt "JA, Schlüssel/ID/Bild/WasAuchImmer ist OK" und diese Stelle springt man dann einfach immer an...


ich dachte an eine entschlüsselung, die nicht kontrolliert, ob der code richtig ist, sondern je nach code ein anderes bild rauskommt und (fast) nur beim richtigen code dann das richtige bild rauskommt. Hoffe mal, dass das so möglich ist, sollte doch eigentlich gehen, oder?

user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
MD5 ist keine Verschlüsselung, sondern ein Hashwert. Ginge aber damit.

Versteh ich dich richtig: Dein Programm ist darauf angewiesen, dass die Bilder auf den Pixel korrekt sein müssen?
Rein aus Interesse: Was ist das für ein Programm, bzw. was hat es mit den Bildern auf sich?

Wenn ich das richtig verstehe, wäre es wohl ne Möglichkeit.. wobei solche Hardware IDs immer den Nachteil haben, dass man einen neuen Schlüssel braucht, sobald man seinen Rechner aufrüstet.
Wie wäre es einfach mit einem USB Dongle?


Also das Programm vergleicht Bilder einer Flashanwendung, so kann es z.B. bei einer Poker Anwendung die Karten analysieren und die Wahrscheinlichkeiten berechnen.
Die Bilder müssen nicht ganz genau auf den Pixel korrekt sein, aber schon sehr wenige falsche Pixel bewirken, dass es nicht mehr funktioniert

Und zum USB-Dongle - wie genau funktioniert das? Also wenn dann jeder der das benutzen will von mir vorher ein USB-Stick kriegen muss, fänd ich nicht gut und zuviel Aufwand, ich bevorzuge eine Softwarelösung.

Also wenn jemand noch ne Idee zur ID hat oder weiß, mit welchem Befehl man die ausliest - bitte melden!
Und wenn jemand ne gute Idee hat für die Verschlüsselung der Bider - ich dachte an was wie z.B. Bild in 4 oder mehr Bereiche teilen, und im ersten Bereich dann z.B. jeden r Wert von den Pixel um einen bestimmten wert, der evtl aus der ID generiert wird ändern, g und b wert um einen anderen wert und in den anderen bereichen um andere werte und dann soll das originalbild nur wiederkommen, wenn man den richtigen code hat und die richtige ID erkannt wird.


Sirke - Fr 26.02.10 20:07

Habe ich das richtig verstanden: Du möchtest mit deinem Programm Bilder in einer anderen Anwendung vergleichen, wobei die Referezbilder in verschlüsselter Form vorliegen, sodass für einen korrekten Vergleich die Referenzbilder entschlüsselt sein müssen?

Dabei hat du das Problem, dass deine Bilder iwann im Arbeitsspeicher in unverschlüsselter Form vorliegen müssen, sodass die Entschlüsselung relativ leicht umgangen werden kann. Diese Möglichkeit besteht IMMER, wenn du mit Daten in unverschlüsselter Form arbeitest, weil du einer Funktion unverschlüsselte Daten übergibst und unverschlüsselte Daten ausgegeben werden! Wenndu jedoch eine Funktion findest, welcher du zwei verschlüsselte Daten übergibst, dh die zu vergleichenden Bilder verschlüsselst du vor dem Eingeben in die Funktion, und die einen verschlüsselten Wert ausgibt, dann kannst du das Problem beheben... ;-) Es gibt Lösungen für solche Probleme, aber die sind sehr rechenintensiv und erlauben nur wenige Operationen!

Du benötigst um es sicher zu halten eine Blackbox für einen gewissen Teil des Programmes oder einen Teil, welcher bekannt ist, aber wo die Eingaben unbekannt sind!


P@u1 - Fr 26.02.10 20:31

Das mit ausm Arbeitsspeicher auslesen werde ich ignorieren, soviel Aufwand wird sich bestimmmt keiner dafür machen.
Aber eine einfache Überprüfung nimmt man halt zu schnell raus, deswegen denke ich mal, dass ich das mit den bildern wie oben beschrieben machen werde.
Problem ist nur noch die Umsetzung, ich kenn mich mit der Bestimmung der ID und mit ver-/entschlüsseln leider überhaupt nicht aus.


Astat - Fr 26.02.10 21:36

Hallo P@u, eine Machine ID erzeugen, findest du hier.

http://www.delphipraxis.net/post438444.html

lg. Astat


P@u1 - Mi 03.03.10 22:08

vielen dank für den link, ich hab mir das mal angeguckt.

Nun aber zum verschlüsseln von Bildern - hat wer ne idee, wie das geht? Es muss kein besonders guter Schutz sein. Am besten wäre es, dass das nicht so funktioniert, dass man nen passwort eingbit und dann nur etwas passiert, wenn es richtig ist, sondern, dass immer was passiert, aber nur beim richtigen passwort (oder bei ein paar kollidierenden, was nicht so schlimm wäre) das richtige bild rauskommt.


uall@ogc - Mi 03.03.10 22:17

Du kannst die einzelnenFarben des Bildes mit dem Password verknüpfen (siehe Scanline und z.B. xor).
Aber auch dann muss man nur einmal ein Passwort haben für eine Machine ID haben und man kann dieimmer wieder entschlüsseln. bzw entschlüsselt die einmal und verwendet dann diese Bilder...


P@u1 - Mi 03.03.10 22:23

diese risiken sind nicht so schlimm.
Scanline habe ich bereits benutzt.
Ich weiß nur noch nicht wie das mit dem Xor geht, aber ich gucks mir mal an


platzwart - Mi 03.03.10 22:38

Irre ich mich, oder ist es eigentlich egal, wie das Passwort gespeichert wird (Bild, Text, was auch immer)?!? Entscheidend sind doch ganz andere Stellen, wie z.B. Dekompilierung des Sourcecodes... oder denke ich grad völlig falsch?


uall@ogc - Mi 03.03.10 22:49

Naja, wenn man kein gültiges Passwort hat dann weiß man ja auch nicht wie das Bild aussieht (jedenfalls wenn man nicht über irgendwelche Analysen das Passwort rausbekommt [z.B. wäre ja einfache XOR verknüofung bei schwarzen Pixel dann direkt das passwort]
Es ist halt so, als wenn du den Code verschlüsselst den du dannja nicht aufrufen kannst.
Sofern du aber einmal ein Passwort hast ist die verschlüsselung nicht mehr der Angriffspunkt, dann nimmt man die entschlüsselten Daten (Bilder) und lädt diese direkt in den Speicher und schmeisst die entschlüsselung komplett raus.


P@u1 - Mi 03.03.10 22:50

es geht nicht um eine speicherung des passworts.

Zum Programm gehören einige Bilder, die für die Funktion des Programms unerlässlich sind.
Wenn man jetzt die Bilder verschlüsselt, kann das Programm nur mit dem richtigen Code, der die Bilder richtig entschlüsselt verwendet werden.
Problem ist im Moment noch das erstellen einer guten ID, wo ich gerade noch dran arbeite und die verschlüsselung


uall@ogc - Mi 03.03.10 22:55

Ja hat auch keiner gesagt. Aber wenn du z.B. das Bild Pixel per Pixel mit XOR "verschlüsselt" dann istdas Passwort (welches du zum verschlüsseln verwendet hast) bei schwarzen Pixeln direkt auslesbar. Ob das nun ein generierter Code ist oder ein Passwort was eingegeben werden muss ist dafür ja egal.

Außerdem kann ma, wenn man weiß wie der Code erstellt wurde, diesen einfach selbst erzeugen.

Und wenn einmal die Bilder entschlüsselt sind, dann kann man diese eben auch kopieren und auf jedem PC verwenden.


platzwart - Mi 03.03.10 23:13

user profile iconP@u1 hat folgendes geschrieben Zum zitierten Posting springen:

Zum Programm gehören einige Bilder, die für die Funktion des Programms unerlässlich sind.
Wenn man jetzt die Bilder verschlüsselt, kann das Programm nur mit dem richtigen Code, der die Bilder richtig entschlüsselt verwendet werden.


Ja, ABER: Wenn ich die Exe einfach dekompiliere und deine Funktionsaufrufe a la "DecodePicture" einfach ausheble... Ist ja exakt das gleiche, als ob ich nach einem Passwort im Quelltext suche...


P@u1 - Mi 03.03.10 23:15

user profile iconplatzwart hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconP@u1 hat folgendes geschrieben Zum zitierten Posting springen:

Zum Programm gehören einige Bilder, die für die Funktion des Programms unerlässlich sind.
Wenn man jetzt die Bilder verschlüsselt, kann das Programm nur mit dem richtigen Code, der die Bilder richtig entschlüsselt verwendet werden.


Ja, ABER: Wenn ich die Exe einfach dekompiliere und deine Funktionsaufrufe a la "DecodePicture" einfach ausheble... Ist ja exakt das gleiche, als ob ich nach einem Passwort im Quelltext suche...


Eben nicht, es wird ja nicht geprüft, ob das passwort richtig oder falsch ist, sondern je nach passwort sieht das endbild nur anders aus. Das programm funktioniert aber nur wenn die bilder richtig aussehen.


user profile iconAstat hat folgendes geschrieben Zum zitierten Posting springen:
Hallo P@u, eine Machine ID erzeugen, findest du hier.

http://www.delphipraxis.net/post438444.html

lg. Astat


Ich hab das mal getestet, bei mir wechselt das zwischen 2 verschiedenen ergebnissen wenn ich mehrmals auf den button drücke, das ist irgendwie komisch.

Edit: Mir ist gerade folgendes aufgefallen:
Eine registrierte Version könnte weitergegeben werden und dann muss nur noch das programm dekompiliert werden und die funktion die die hardware id bestimmt so umzuschreiben, dass genau die hardwareid rauskommt, die die person verwendet hat, die die version registriert hat. dann kann er das programm mit dem selben passwort benutzen. Also ist die verwendung von hardwareid gar nicht so besonders sinnvoll, oder habe ich hier einen denkfehler?


platzwart - Mi 03.03.10 23:40

Naja, dann wird eben jemand die entschlüsselten Bilder verbreiten.


Xentar - Mi 03.03.10 23:41

Meinste nicht, du machst dir da etwas zuviel Mühe?
Über die Forensuche finden sich bestimmt genug Themen, warum es keinen "perfekten" Kopierschutz gibt..

Steck die Arbeit lieber darein, das eigentliche Programm zu verbessern.


P@u1 - Mi 03.03.10 23:46

ich will ja keinen perfekten kopierschutz, nur einen relativ leichten, aber er sollte schon so anspruchsvoll sein, dass man nicht bloß eine abfrage rausnehmen muss. Dazu hatte ich halt nen paar Ideen die ich ja geschrieben habe, wenn jemand andere Ideen für einen solchen schutz hat, immer her damit plz, langsam bin ich nämlich auch der ansicht, dass mein ansatz zu kompliziert war.
Aber ich sehe im Moment keinen weg an einer hardware id vorbei, um das weitergeben zu verhindern.

Edit: zu den 2 verschiedenen hardware ids die rauskamen mit dem einen programm: kann es sein, dass das an dual-core liegt?


Sirke - Do 04.03.10 02:48

Ich habe schon ein Mal ein Variante geschrieben, welche Funktionieren KANN, wenn man sich Gedanken macht: Dann generierst du auf jedem Rechner eine eindeutige ID, welche der Schlüssel für die Funktionen ist und lässt dir diese ID zukommen. Anschließend verschlüsselst du deine Vergleichsbilder mit der ID und sendest das Programm mit den verschlüsselten Bildern an den Benutzer.
In dem Programm werden die verschlüsselte Vegleichsbilder geladen und anschließend das zu vergleichende Bild verschlüsslet und beide in die Vergleichsfunktion gegeben. Diese gibt dann den Wert der "Gleichheit" oder was auch immer aus...

Diese Variante KANN funktionieren, sofern die Vergleichsfunktion bestimmte Voraussetzungen erfüllt, sodass man eine Verschlüsselung mit ihr nutzen kann! Außerdem ist das ganze nur eine Idee in meinem Kopf und muss daher nicht funktionieren...


Gausi - Do 04.03.10 08:43

Joah, und wer dann einen halben Meter Ahnung vom cracken hat, hat das Ding in 30 Sekunden ausgehebelt, weil er die Abfrage "if Vergleichswert OK " in "if Vergleichswert nicht OK" ändert. Da kann die Berechnung noch so kompliziert sein, am Ende ist da die Schwachstelle.

Ich habe das mit dem Bild hier sowieso noch nicht ganz verstanden, was das bringen soll. Hat das entschlüsselte Bild selbst eine Funktion für das Programm? :gruebel:


P@u1 - Do 04.03.10 16:06

user profile iconGausi hat folgendes geschrieben Zum zitierten Posting springen:

Ich habe das mit dem Bild hier sowieso noch nicht ganz verstanden, was das bringen soll. Hat das entschlüsselte Bild selbst eine Funktion für das Programm? :gruebel:


Ja genau, das Bild wird vom Programm benutzt. Es ist nicht bloß für eine Sicherheitsüberprüfung da, sondern das Bild selbst wird für die Funktion des Programms benötitgt.
Ohne das Bild funktioniert es nicht.

Das Problem beim erstellen der ID ist immer noch, dass bei mir 2 verschiedene rauskommen, was vermutlich an dualcore liegt.

Edit: glaube ich hab das dual-core hiermit gelöst:

Delphi-Quelltext
1:
SetProcessAffinityMask(GetCurrentProcess, 1);                    


und wenn ich dann

Delphi-Quelltext
1:
SetProcessAffinityMask(GetCurrentProcess, 0);                    

mache ist es wieder auf beide CPUs verteilt (glaube ich zumindest)


Bergmann89 - Do 04.03.10 19:57

Hey,

in dem Thread [http://www.delphi-forum.de/viewtopic.php?t=92484] gibts ne Unit, damit kannst du die Bilder über nen Stream-Adapter laden. Der verschlüsselt und entschlüsselt das dann auch alles gleich.

MfG Bergmann.


P@u1 - Sa 06.03.10 19:13

Ich habe mir jetzt eine eigene Verschlüsselung geschrieben, die jeden Pixel einzeln über Pixels ändert.
Allerdings gibt es ein großes Problem:

Irgendwie scheint der Befehl Scanline verrückt zu spielen, wenn ein Bild über den Pixels befehl geändert wurde.

Meine Funktion, die zwei Bilder über Scanline vergleicht erkennt schon einen SEHR großen Fehler, wenn ich folgendes mache:

zuerst lade ich in bmp und bmp2 das selbe bild rein, dann kommt nur das hier, was eigentlich NICHTS ändern dürfte:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
  for i := 0 to Image2.Picture.Bitmap.Width do
  begin
    for j := 0 to Image2.Picture.BitMap.Height do
    begin
      bmp2.Canvas.Pixel[i,j]:=bmp2.Canvas.Pixel[i,j];
    end;
  end;


vor diesen befehlen hat die vergleichsfunktion die mit scanline arbeitet keinen unterschied erkannt, danach einen sehr großen, obwohl die bilder absolut identisch aussehen und sogar exakt die selbe größe haben, wenn ich sie speichere.

Kann mir das irgendjemand vielleicht erklären bitte?


platzwart - Sa 06.03.10 19:19

Welches Dateiformat?


P@u1 - Sa 06.03.10 19:25

Bitmap

Edit: hab gerade mal die md5 hashs überprüft, sind unterschiedlich, obwohl die bilder exakt gleich aussehen und eigentlich jeder pixel nur auf seinen eigenen wert gesetzt wurde.........

Ich versteh das nicht!

Und wie kann ich dieses Problem lösen?

Edit2:

Hab vor dem Vergleich diese Zeilen benutzt:

Delphi-Quelltext
1:
2:
  bmp1.PixelFormat:=pf24bit;
  bmp2.PixelFormat:=pf24bit;


Jetzt werden die Bilder wieder als gleich erkannt!

Verstehen tu ichs aber immer noch nicht!