Skip to Content
Neue Version 12 verfügbar 🎉
LicensingLizenzgebundene Codeverschlüsselung

Lizenzgebundene Codeverschlüsselung

Machen Sie eine geschützte Funktion kryptografisch von einer gültigen Lizenz abhängig, indem Sie das Passwort der Codeverschlüsselung in der Lizenz selbst ablegen.

Eine boolesche Lizenzprüfung wie if (!IsLicensed) return; lässt sich leicht herauspatchen. Dieses Beispiel zeigt ein stärkeres Muster: Die sensible Methode wird mit der Codeverschlüsselung von Babel Obfuscator verschlüsselt, und das Passwort, das die Babel Virtual Machine (BVM) zu ihrer Ausführung braucht, steht gar nicht in der Binärdatei. Es liegt, selbst verschlüsselt, in einer signierten und hardwaregebundenen Babel-Lizenz. Die Lizenzprüfung zu entfernen genügt nicht: Ohne gültige Lizenz gibt es kein Passwort, und ohne das Passwort lässt sich die verschlüsselte Methode weder rekonstruieren noch ausführen.

Codebeispiel

git clone https://github.com/babelfornet/license-bound-encryption-console-example.git

Das Projekt ist eine plattformübergreifende .NET-Konsolenanwendung mit zwei Teilen: SecureApp, die lizenzierte Anwendung, deren sensible Methode codeverschlüsselt ist, und LicenseGenerator, ein Tool auf Herstellerseite, das signierte Lizenzen ausstellt. Die Version des Babel-Pakets ist zentral in Directory.Build.props festgelegt, sodass das Beispiel die Version verwenden kann, die zu Ihrem Feed passt.

Die geschützte Methode

Das zu schützende geistige Eigentum ist eine einzige Methode. Das Attribut [Obfuscation] weist Babel an, ihren Rumpf zu verschlüsseln und ihn in der Assembly (internal=true) unter dem Quellnamen core abzulegen, mit einem Passwort, das beim Build verwendet wird:

[Obfuscation(Feature = "msil encryption:internal=true;source=core;password=C0re-Pr0tect!on-K3y", Exclude = false)] public static long Compute(int a, int b) { long acc = 0; for (int i = 1; i <= b; i++) acc += (long)a * i; return acc + 42; }

Die Codeverschlüsselung ist nur im Release-Build eingeschaltet und über eine MSBuild-Eigenschaft in SecureApp.csproj auf die sensible Klasse begrenzt:

<PropertyGroup Condition="'$(Configuration)' == 'Release'"> <MsilEncryption Condition="'$(MsilEncryption)' == ''">SecureApp\.Secret::.*</MsilEncryption> <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors> </PropertyGroup>

Die Codeverschlüsselung läuft nur in der Konfiguration Release. Die Zeile BabelWarningsAsErrors macht aus der Warnung W00000 des Evaluierungsmodus einen Fehler, sodass eine ungeschützte Assembly nie versehentlich ausgeliefert werden kann.

Wo das Passwort liegt

Beim Build wird die Methode mit dem Passwort C0re-Pr0tect!on-K3y verschlüsselt. Zur Laufzeit fragt die BVM die Anwendung über einen Hook get password nach diesem Passwort, bevor sie die Methode ausführen kann. Statt einen fest codierten Wert zurückzugeben, validiert der Hook die Lizenz und liest das Passwort aus ihr:

[Obfuscation(Feature = "msil encryption get password")] internal static string GetSourcePassword(string source) { var license = Validate(); // The code password is carried by the license as an encrypted field. var field = license.Fields.FirstOrDefault(f => f.Name == source) ?? throw new InvalidOperationException($"License does not grant source '{source}'."); // Decrypt the field with the vendor secret to recover the real code password. return field.Value.Decrypt(Secrets.FieldSecret); }

Validate() verwendet den eingebetteten öffentlichen RSA-Schlüssel, um die Signatur der Lizenz zu prüfen, und erzwingt jede Einschränkung, einschließlich der Hardwarebindung:

public static ILicense Validate() { var manager = new StringLicenseManager { SignatureProvider = RSASignature.FromKeys(PublicKey) }; return manager.Validate(File.ReadAllText(LicenseFilePath), typeof(Program)); }

Die Lizenz ausstellen

Der LicenseGenerator auf Herstellerseite signiert eine Lizenz, die an die Assembly SecureApp und an den aktuellen Rechner gebunden ist und das Codepasswort als verschlüsseltes Feld enthält. Das Passwort erscheint daher nie im Klartext, weder in der Binärdatei noch in der Lizenzdatei:

string encryptedPassword = Secrets.CodePassword.Encrypt(Secrets.FieldSecret); var license = new StringLicense() .ForAssembly(assemblyFullName) .WithUniqueId("SECURE-") .WithHardwareKey(HardwareId.Create().ToMachineKey()) .WithField(Secrets.Source, encryptedPassword) .LicensedTo("Demo Customer", "demo@example.com", "ACME Corp"); string serial = license.SignWith(signature).ToReadableString("ASCII");

Der LicenseGenerator und der private RSA-Schlüssel (keys.pem) dienen nur der Demonstration. In der Produktion stellt der Hersteller oder der Babel Licensing Service die Lizenz aus, und der private Schlüssel wird offline aufbewahrt. Mit der Anwendung wird nur der öffentliche Schlüssel ausgeliefert.

Ausführen

# Build the app in Release — this is when Babel encrypts Secret.Compute. dotnet build src/SecureApp/SecureApp.csproj -c Release # Generate a signed, machine-locked license. dotnet run --project src/LicenseGenerator # Deploy the license next to the app and run it. cp SecureApp.lic src/SecureApp/bin/Release/net8.0/ dotnet src/SecureApp/bin/Release/net8.0/SecureApp.dll

Mit einer gültigen Lizenz läuft die geschützte Methode:

License OK : SECURE-8CCC8 Licensed to : Demo Customer Bound to machine: ADSQH-89GGJ-J7CJY-3FQFK-DF48H Protected computation Secret.Compute(7, 5) = 147 The encrypted method ran: the license unlocked the code.

Wenn Sie SecureApp.lic entfernen oder manipulieren oder die Anwendung auf einem anderen Rechner ausführen, ist das Ergebnis mehr als eine freundlichere Fehlermeldung: Der verschlüsselte Code kann schlicht nicht ausgeführt werden.

License INVALID : Invalid license signature Protected computation blocked: Invalid license signature Without a valid license the encrypted code cannot be decrypted or executed.

Warum dies stärker ist

Weil das Passwort aus einer signierten Lizenz stammt, gewinnt ein Angreifer nichts, wenn er den Validierungscode aus der Assembly entfernt: Die BVM hat weiterhin kein Passwort für die Quelle core, und Secret.Compute bleibt ein undurchsichtiger, verschlüsselter Blob. Die Signatur verhindert, dass eine Lizenz gefälscht wird, und die Hardwarebindung verhindert, dass eine rechtmäßige Lizenz auf einem anderen Rechner wiederverwendet wird. Dieselbe Technik liegt dem Beispiel Funktionsbasierte Lizenzen und den vom Hersteller gehosteten Lizenzvorlagen zugrunde, bei denen der Babel Licensing Service das verschlüsselte Feld liefert und nicht ein lokaler Generator.

Last updated on