Standardalgorithmen
Babel Obfuscator wird mit drei integrierten Algorithmen für die Zeichenfolgenverschlüsselung ausgeliefert: XOR, HASH und STREAM. Alle drei sind eigenständig, das heißt, sie entschlüsseln ohne externe Eingabe. Die Wahl zwischen ihnen ist daher eine Abwägung zwischen Ladezeit, Ausgabegröße und dem Aufwand, mit dem sich die Zeichenfolgen wiederherstellen lassen. Diese Seite beschreibt jeden Algorithmus und wie Sie ihn einschalten. Die Vergleichstabelle am Ende fasst die Unterschiede zusammen.
Algorithmus XOR
Der Algorithmus XOR, den Babel Obfuscator für die Zeichenfolgenverschlüsselung verwendet, ist ein einfaches Verfahren: Die Zeichen der im Code enthaltenen Zeichenfolge werden per XOR mit einem zufälligen ganzzahligen Schlüssel verknüpft. Der Vorteil dieses Verfahrens ist eine schnellere Entschlüsselung und eine kürzere Ladezeit als bei anderen Verschlüsselungsalgorithmen.
Befehlszeile
Um den Verschlüsselungsalgorithmus XOR für Ihre Anwendung mit Babel Obfuscator auf der Befehlszeile zu konfigurieren, verwenden Sie diesen einfachen Befehl:
babel myapp.exe --string xorDieser Befehl weist Babel an, die im Code enthaltenen Zeichenfolgen der ausführbaren Datei Ihrer Anwendung mit XOR zu verschlüsseln. Er nutzt die Einfachheit und die Geschwindigkeit des Algorithmus XOR für eine sichere Verschleierung der Zeichenfolgen.
MSBuild-Aufgabe Babel
Der Algorithmus XOR für die Zeichenfolgenverschlüsselung lässt sich in Ihrem Projekt mit der MSBuild-Aufgabe Babel leicht konfigurieren. Fügen Sie Ihrer MSBuild-Projektdatei eine Eigenschaftengruppe und eine Babel-Aufgabe mit der Konfiguration für das Verschlüsselungsverfahren XOR hinzu:
<PropertyGroup>
<StringEncryption>xor</StringEncryption>
</PropertyGroup>
<Babel StringEncryption="$(StringEncryption)" />Mit dieser Konfiguration wendet Babel Obfuscator den Verschlüsselungsalgorithmus XOR auf die Zeichenfolgen Ihres Projekts an. Das erhöht ihre Sicherheit und macht sie widerstandsfähiger gegen Manipulation und Reverse Engineering.
Algorithmus HASH
Der Algorithmus HASH von Babel Obfuscator beruht auf Hashtabellen, die über ganzzahlige Schlüssel adressiert werden. Dieser Algorithmus komprimiert und verschlüsselt die Zeichenfolgendaten, was deren Gesamtgröße in der Datei verringern kann. Weil die komprimierten Zeichenfolgendaten zur Laufzeit entschlüsselt werden müssen, kann sich das jedoch auf die Ladezeit der Anwendung auswirken. Verglichen mit dem Algorithmus XOR, der die Zeichen der im Code enthaltenen Zeichenfolge per XOR mit einem zufälligen ganzzahligen Schlüssel verknüpft, schützt der Algorithmus HASH besser vor Angriffen auf die Entschlüsselung der Zeichenfolgen, allerdings um den Preis einer längeren Ladezeit.
Befehlszeile
Um die HASH-Verschlüsselung mit Babel Obfuscator über die CLI einzurichten, verwenden Sie diesen Befehl:
babel myapp.exe --string hashMSBuild-Aufgabe Babel
Um die HASH-Verschlüsselung mit der MSBuild-Aufgabe von Babel einzuschalten, setzen Sie die Eigenschaft StringEncryption wie folgt:
<PropertyGroup>
<StringEncryption>hash</StringEncryption>
</PropertyGroup>
<Babel StringEncryption="$(StringEncryption)" />Durch diese Einbindung des Algorithmus HASH sind die Zeichenfolgen Ihres Projekts während des Builds angemessen geschützt.
Algorithmus STREAM Ultimate
Der Algorithmus STREAM ist die moderne, authentifizierte Variante der Zeichenfolgenverschlüsselung in Babel Obfuscator. Er verschlüsselt jede Zeichenfolge einzeln mit einer starken, branchenüblichen Chiffre und prüft ein Authentifizierungstag, bevor er sie zurückgibt. Damit hat STREAM vier Eigenschaften, die den älteren Algorithmen fehlen:
- Verzögerte Entschlüsselung je Zeichenfolge. Eine Zeichenfolge wird erst entschlüsselt, wenn sie zum ersten Mal tatsächlich verwendet wird, und das Ergebnis wird zwischengespeichert. Anders als HASH entschlüsselt STREAM nie die gesamte Menge im Voraus. Ein Speicherabbild legt daher immer nur die wenigen Zeichenfolgen offen, die die Anwendung bereits verwendet hat: Es gibt keinen Zeitpunkt, zu dem alle Zeichenfolgen im Klartext im Speicher liegen.
- Integrität und Randomisierung je Zeichenfolge. Das Authentifizierungstag erkennt jede Manipulation der verschlüsselten Daten, und zwei identische Zeichenfolgen werden zu unterschiedlichen Bytes verschlüsselt. Das vereitelt die Häufigkeits- und Gleichheitsanalyse, für die ein einfaches XOR-Schema anfällig ist.
- Ein Schlüssel, der nie inline gespeichert wird. Der Schlüssel steht nicht als Literal neben dem Entschlüsselungsaufruf. Ein automatischer Deobfuskator muss deshalb den echten Code ausführen, um eine Zeichenfolge wiederherzustellen, statt einfach einen Schlüssel neben dem Aufruf abzulesen.
- Entschlüsselung, die an den Aufrufkontext Ihres Codes gebunden ist. Es genügt nicht, die Entschlüsselungsroutine auszuführen: Sie gibt eine Zeichenfolge nur an einen Aufrufer zurück, der innerhalb der geschützten Assembly selbst läuft (oder innerhalb der .NET-Laufzeit, damit LINQ/PLINQ und asynchrone Pfade weiter funktionieren). Der übliche Weg, auf dem ein automatischer Deobfuskator mit einem einzigen Befehl alle verschlüsselten Zeichenfolgen auf einmal ausliest, wird damit abgewiesen: einen Delegaten direkt an die Entschlüsselungsroutine zu binden und ihn aus der eigenen Hilfs-Assembly stapelweise aufzurufen. Das macht es nicht unmöglich, Zeichenfolgen bei vollständiger dynamischer Analyse wiederherzustellen. Es versperrt aber den billigen Weg der Massenextraktion und zwingt einen Angreifer, Ihren echten Code auszuführen.
Die Entschlüsselungsroutine ist vollständig in verwaltetem Code geschrieben und hängt nicht vom Kryptografieanbieter der Plattform ab. Deshalb läuft STREAM unverändert von .NET Framework 4.x (und 2.0) bis .NET 10, unter Mono/Xamarin und, weil kein Reflection.Emit verwendet wird, in NativeAOT- und getrimmten Anwendungen. Auch das FIPS-Problem beim Start, das die plattformbasierten Algorithmen treffen kann, betrifft STREAM nicht.
STREAM ist eigenständig und entschlüsselt wie XOR und HASH ohne externe Eingabe. Als rein lokales Verfahren kann STREAM nicht verhindern, dass Zeichenfolgen bei vollständiger dynamischer Analyse wiederhergestellt werden. Das kann kein eigenständiges Verfahren. STREAM hebt aber den Aufwand für die automatische Extraktion und für das manuelle Reverse Engineering deutlich über den von XOR und HASH.
Plattform- und Frameworkunterstützung
Weil die Entschlüsselungsroutine vollständig verwaltet ist und weder Reflection.Emit noch dynamischen Code, Stack-Walking oder den Kryptografieanbieter der Plattform verwendet, wurde STREAM über die gesamte Bandbreite von .NET und auf Mobilgeräten geprüft:
- .NET Framework 2.0 / 4.x bis .NET 10, .NET Core und Mono / Xamarin.
- Getrimmte (ILLink) und NativeAOT-Anwendungen: Die eingefügte Entschlüsselungsroutine und ihre eingebettete Zeichenfolgentabelle überstehen das Linken, und der Code wird im Voraus ohne JIT kompiliert.
- Android und iOS: durchgängig geprüft mit echten verschleierten Apps im Android-Emulator und im iOS-Simulator, einschließlich vollständig getrimmter Release-Builds. Die Zeichenfolgen werden zur Laufzeit entschlüsselt, und in der verpackten Assembly bleibt kein Klartext zurück. .NET MAUI baut auf denselben Laufzeiten auf (
net*-android/net*-ios), daher gilt dieselbe Unterstützung. Full-AOT auf iOS-Geräten ist durch die oben genannte NativeAOT-Kompatibilität abgedeckt.
Wenden Sie STREAM auf Mobilgeräten in einem Durchgang an, der nur Zeichenfolgen verschlüsselt, damit die Namen von Typen und Membern für die Interop-Schicht zu Java / Objective-C erhalten bleiben:
babel MyApp.dll --stringencryption stream --notypes --nomethods --nofields --noproperties --noevents --noparameters --novirtualmembersLäuft Babel als MSBuild-Schritt in einem Build für .NET Android / iOS / MAUI, hängen Sie es ein, nachdem die App-Assembly kompiliert wurde und bevor das Paket erstellt wird, damit die verpackte App die verschleierte Assembly enthält.
Befehlszeile
So wenden Sie die STREAM-Verschlüsselung auf der Befehlszeile an:
babel myapp.exe --string streamMSBuild-Aufgabe Babel
Um die STREAM-Verschlüsselung mit der MSBuild-Aufgabe von Babel einzuschalten, setzen Sie die Eigenschaft StringEncryption wie folgt:
<PropertyGroup>
<StringEncryption>stream</StringEncryption>
</PropertyGroup>
<Babel StringEncryption="$(StringEncryption)" />STREAM arbeitet mit den anderen Schutzfunktionen zusammen und lässt sich in derselben Assembly mit der Codeverschlüsselung (MSIL) und der Manipulationserkennung kombinieren.
Manipulationserkennung und Umschreiben nach dem Build. Die Manipulationserkennung prägt dem verschleierten Abbild einen Integritätshash ein. Jeder Schritt, der die Assembly nach Babel umschreibt, ändert diese Bytes und lässt die Prüfung sofort beim Start fehlschlagen. Das gilt vor allem für eine getrimmte oder NativeAOT-Veröffentlichung, die die verwaltete Assembly neu ausgibt. Dieses Verhalten liegt in der Natur der Manipulationserkennung und hängt nicht vom Zeichenfolgenalgorithmus ab (es betrifft XOR, HASH und STREAM gleichermaßen): Schalten Sie die Manipulationserkennung bei Builds ein, die nicht weiter getrimmt oder per AOT umgeschrieben werden, und verlassen Sie sich bei getrimmten Ausgaben und AOT-Ausgaben auf die Zeichenfolgenverschlüsselung (und die Codeverschlüsselung).
Die Algorithmen vergleichen
Alle drei integrierten Algorithmen sind eigenständig, das heißt, sie entschlüsseln ohne externe Eingabe. Die Wahl zwischen ihnen ist daher eine Abwägung zwischen Ladezeit, Ausgabegröße und dem Aufwand, mit dem sich die Zeichenfolgen wiederherstellen lassen.
| XOR | HASH | STREAM | |
|---|---|---|---|
| Chiffre | Inline-XOR mit einem ganzzahligen Schlüssel je Zeichenfolge | Komprimierte Tabelle, mit der Chiffre der Plattform verschlüsselt | Authentifizierte, branchenübliche Chiffre je Zeichenfolge |
| Zeichenfolgen bleiben als Literale erhalten | Ja (an Ort und Stelle verwürfelt) | Nein | Nein |
| Entschlüsselungsmodell | Je Zeichenfolge, bei jedem Zugriff | Sofort: Die gesamte Tabelle wird bei der ersten Verwendung entschlüsselt | Verzögert: jede Zeichenfolge bei der ersten Verwendung, danach zwischengespeichert |
| Klartext im Speicher | Jeweils eine Zeichenfolge | Die gesamte Tabelle, solange die Anwendung läuft | Nur die tatsächlich verwendeten Zeichenfolgen |
| Integritätstag je Zeichenfolge | — | — | Ja |
| Identische Zeichenfolgen werden unterschiedlich verschlüsselt | Nein | Nein | Ja |
| Verweigert die Entschlüsselung außerhalb des Kontexts (Aufruf über einen Delegaten) | — | — | Ja |
| Entschlüsselungsschlüssel | Inline, neben dem Aufruf | Im Header des Blobs gespeichert | Nie inline: zur Laufzeit neu aufgebaut und in den Kontrollfluss eingewoben |
| Vollständig verwaltete Entschlüsselungsroutine (kein Kryptografieanbieter der Plattform; FIPS-sicher) | Nein | Nein | Ja |
| Relative Ausgabegröße | Am größten (die Literale bleiben in der Assembly) | Am kleinsten (ein einziger komprimierter Blob) | Zwischen XOR und HASH |
| Relative Laufzeitkosten | Am niedrigsten | Niedrig, fallen aber im Voraus für jede Zeichenfolge an | Höher je Zeichenfolge, fallen nur für verwendete Zeichenfolgen an |
Welchen Algorithmus Sie wählen sollten.
- XOR: der schnellste und leichteste, aber auch der schwächste Algorithmus. Die verschlüsselten Zeichenfolgen bleiben als Literale in der Assembly, und neben jedem Aufruf steht ein Schlüssel je Zeichenfolge, sodass ein automatisches Tool sie in einem einzigen Durchgang wiederherstellen kann. Wählen Sie ihn, wenn die Ladezeit wichtiger ist als der Schutz.
- HASH: entfernt die Literale und packt die gesamte Menge in einen einzigen komprimierten, verschlüsselten Blob (die kleinste Ausgabe), mit Manipulationsschutz für die Tabelle. Der Preis dafür: Die gesamte Tabelle wird bei der ersten Verwendung sofort entschlüsselt, sodass jede Zeichenfolge im Klartext im Speicher liegt, solange die Anwendung läuft, und die Entschlüsselungsroutine ist auf den Kryptografieanbieter der Plattform angewiesen (siehe den Hinweis zu FIPS).
- STREAM: der stärkste der drei Algorithmen gegen statische wie dynamische Analyse. Er bietet authentifizierte Verschlüsselung je Zeichenfolge, keine sofortige globale Entschlüsselung, keinen Inline-Schlüssel und eine einzige, vollständig verwaltete Entschlüsselungsroutine, die sich unverändert mit NativeAOT und Trimming veröffentlichen lässt und von FIPS nicht betroffen ist. Die Entschlüsselung kostet je Zeichenfolge mehr, aber nur für die Zeichenfolgen, die die Anwendung tatsächlich verwendet, und zu keinem Zeitpunkt liegt die gesamte Menge der Zeichenfolgen im Klartext vor. Bevorzugen Sie STREAM für modernes .NET, für Bereitstellungen mit AOT, Trimming oder FIPS und überall dort, wo der Widerstand gegen die Massenextraktion von Zeichenfolgen am wichtigsten ist.