Skip to Content
Neue Version 12 verfügbar 🎉
LicensingTestlizenz als Seriennummer

Testlizenz als Seriennummer

Mit Testlizenzen bieten Softwarehersteller potenziellen Kunden zeitlich begrenzte Testversionen ihrer Anwendungen an.

Dieser Artikel erläutert das Konzept der Testlizenz als Seriennummer und zeigt ihre Implementierung anhand einer Konsolenanwendung als Beispiel. Der Code zeigt, wie Sie eine Testlizenz erstellen, die nach einer bestimmten Anzahl von Tagen abläuft und die Anzahl der zulässigen Ausführungen begrenzt. Außerdem zeigt er, wie Verschlüsselungstechniken sensiblen Code schützen, der nur ausgeführt wird, wenn die Lizenz gültig ist. Wer das Modell der Testlizenz als Seriennummer versteht und den zugehörigen Code untersucht, erfährt, wie sich mit Babel Licensing Testversionen eigener Softwareprodukte umsetzen lassen.

Codebeispiel

Um den Code des Projekts TrialLicense zu erhalten und näher zu untersuchen, klonen Sie das Repository mit dem folgenden Befehl von GitHub:

git clone https://github.com/babelfornet/trial-license-string-console-example.git

Das Projekt TrialLicense zeigt, wie Sie mit Babel Licensing ein Testlizenzsystem in einer Konsolenanwendung implementieren. Dieses Beispielprojekt ist mit Windows, Linux und macOS kompatibel. Mit dem geklonten Repository haben Sie den vollständigen Quellcode vor sich und können die Einzelheiten der Implementierung, die verschiedenen Komponenten und die Funktionen des Testlizenzsystems untersuchen.

Das Projekt verwendet das NuGet-Paket von Babel Obfuscator, um den Code während des Builds zu verschleiern und zu verschlüsseln.

Um Babel Obfuscator zu aktivieren, setzen Sie die Umgebungsvariable BABEL_LICENSE auf den Pfad der Lizenzdatei oder auf den Floating-Lizenzschlüssel.

Der verschlüsselte Code lässt sich nur mit einer gültigen Seriennummer ausführen, die das Passwort für die Entschlüsselung enthält.

Beispiel für eine Testlizenz

Um die Anwendung zu starten, öffnen Sie ein Shell-Fenster, wechseln Sie in den Ordner Debug des Projekts und führen Sie den Befehl TrialLicense mit ENTER aus. Damit wird die Anwendung ausgeführt.

Testlizenz erzeugen

Der folgende Code erzeugt die Seriennummer einer Testlizenz:

string hardwareKey = HardwareId.Create().ToMachineKey(); var sign = (RSASignature)Pem.ReadSignature("Keys.pem"); var lic = new StringLicense() // Create a new string license .ForAssembly(Assembly.GetExecutingAssembly()) // The license is for this assembly .WithUniqueId() // Unique ID for the license .WithHardwareKey(hardwareKey) // Lock to the current machine .WithTrialDays(2) // Give 2 days trial .WithMaximumRunCount(3) // Allow 3 runs .WithField("source1", "p@ssw0rd1".Encrypt("!sEcr3tp@sswOrD!")) // Set the encrypted code password .SignWith(sign); // Sign the license with the private key // Convert the license object to an ASCII string string serial = lic.ToReadableString("ASCII");

Im Einzelnen geschieht Folgendes:

  1. HardwareId.Create().ToMachineKey() erzeugt einen hardwarespezifischen Schlüssel, der den aktuellen Rechner eindeutig identifiziert. Mit diesem Schlüssel wird die Testlizenz an den aktuellen Rechner gebunden.
  2. (RSASignature)Pem.ReadSignature("Keys.pem") liest den privaten RSA-Schlüssel aus der Datei „Keys.pem“. Mit diesem Schlüssel wird die Lizenz signiert und ihre Echtheit validiert.
  3. new StringLicense() erstellt eine neue Instanz der Klasse StringLicense, die die Testlizenz darstellt.
  4. .ForAssembly(Assembly.GetExecutingAssembly()) legt fest, dass die Lizenz der aktuellen Assembly zugeordnet ist.
  5. .WithUniqueId() erzeugt eine eindeutige ID für die Lizenz.
  6. .WithHardwareKey(hardwareKey) bindet die Lizenz an den aktuellen Rechner, indem es sie mit dem in Punkt 1 erzeugten Hardwareschlüssel verknüpft.
  7. .WithTrialDays(2) setzt den Testzeitraum auf 2 Tage, nach denen die Lizenz abläuft.
  8. .WithMaximumRunCount(3) legt die maximale Anzahl der Ausführungen fest, die für die Testversion zulässig sind.
  9. .WithField("source1", "p@ssw0rd1".Encrypt("!sEcr3tp@sswOrD!")) fügt der Lizenz ein Feld namens „source1“ hinzu und setzt dessen Wert auf ein verschlüsseltes Passwort. Mit diesem Passwort wird bestimmter Code für die Ausführung entschlüsselt, wenn die Lizenz gültig ist.
  10. .SignWith(sign) signiert die Lizenz mit dem in Schritt 2 gelesenen privaten RSA-Schlüssel und sichert so ihre Integrität und Echtheit.
  11. lic.ToReadableString("ASCII") wandelt das Lizenzobjekt in eine ASCII-Zeichenfolge um.
  12. Die so entstandene Seriennummer der Lizenz wird in der Registrierung gespeichert, zusammen mit dem öffentlichen Schlüssel für die Validierung.

Dieser Code zeigt, wie die Seriennummer einer Testlizenz erzeugt, durch Verschlüsselung gesichert und in der Registrierung gespeichert wird. Die Testlizenz lässt sich mit dem zugehörigen öffentlichen Schlüssel validieren, um ihre Echtheit sicherzustellen und die Testeinschränkungen durchzusetzen, etwa die Testdauer und die Begrenzung der Ausführungen.

Testlizenz validieren

Der folgende Codeausschnitt zeigt eine praktische Implementierung dieses Vorgangs. Er validiert die Seriennummer der Testlizenz mit Babel Licensing.

var store = new LicenseStore(); store.Load(); if (store.Serial == null) { Console.WriteLine("No serial found"); return; } // Get the public key from the key to validate the license signature string publicKey = Convert.ToString(store.Key).Decrypt("pk_p@sswOrd"); var manager = new StringLicenseManager(); // The public key is used to validate the license signature manager.SignatureProvider = RSASignature.FromKeys(publicKey); // Validate the serial // A license object is returned if the serial is valid and all license restrictions are met Babel.Licensing.ILicense license = manager.Validate(store.Serial); Console.WriteLine("Serial {0} is valid", license.Id); var trial = license.Restrictions.OfType<TrialRestriction>().FirstOrDefault(); if (trial != null) { Console.WriteLine("Trial time left: {0}", trial.TimeLeft); Console.WriteLine("Runs left: {0}", trial.RunCountLeft); }

Hier wird der öffentliche Schlüssel, mit dem die Signatur der Lizenz validiert wird, aus den Informationen der Lizenzdatei gelesen. Der Wert, der dem Schlüssel „Key“ zugeordnet ist, wird abgerufen, und der gespeicherte Wert wird mit dem Entschlüsselungspasswort „pk_p@sswOrd“ entschlüsselt.

Eine Instanz der Klasse StringLicenseManager wird erstellt, um die Lizenzvalidierung zu steuern. Die Eigenschaft SignatureProvider des Managers wird auf ein Objekt RSASignature gesetzt, das aus dem gelesenen öffentlichen Schlüssel erstellt wurde. Damit verwendet der Manager den öffentlichen Schlüssel, um die Signatur der Lizenz zu validieren.

Babel.Licensing.ILicense license = manager.Validate(serial);

Die Methode manager.Validate(serial) wird aufgerufen, um die Lizenz zu validieren. Als Argument wird die Seriennummer der Lizenz übergeben, die in der Variablen serial gespeichert ist. Ist die Seriennummer gültig und erfüllt sie alle Lizenzeinschränkungen, wird ein Lizenzobjekt zurückgegeben, das die Schnittstelle Babel.Licensing.ILicense implementiert. Es stellt die validierte Lizenz dar.

Zum Schluss werden die verbleibende Testzeit und die Anzahl der verbleibenden Ausführungen auf der Konsole ausgegeben.

Insgesamt validiert dieser Code die Seriennummer einer Lizenz, indem er die Seriennummer und den öffentlichen Schlüssel aus der Registrierung liest, den Lizenzmanager mit dem öffentlichen Schlüssel konfiguriert und die Validierungsmethode aufruft. Anschließend zeigt er das Ergebnis der Validierung und, sofern vorhanden, die zugehörigen Lizenzinformationen wie Testzeit und Anzahl der Ausführungen an.

Verschlüsselten Code ausführen

Der folgende Codeabschnitt zeigt die Ausführung von verschlüsseltem Code und wie Babel Obfuscator das Passwort dafür abruft. So arbeitet dieser Code:

Zunächst sind zwei Methoden beteiligt:

[Obfuscation(Feature = "msil encryption get password", Exclude = false)] internal static string GetEncryptedCodePassword(string source) { return EncryptedGetEncryptedCodePassword(source); } [Obfuscation(Feature = "msil encryption", Exclude = false)] private static string EncryptedGetEncryptedCodePassword(string source) { var store = new LicenseStore(); store.Load(); if (store.Serial == null) { throw new Exception("No serial found"); } // Get the public key from the key to validate the license signature string publicKey = Convert.ToString(store.Key).Decrypt("pk_p@sswOrd"); var manager = new StringLicenseManager(); // The public key is used to validate the license signature manager.SignatureProvider = RSASignature.FromKeys(publicKey); // Validate the serial // A license object is returned if the serial is valid and all license restrictions are met Babel.Licensing.ILicense license = manager.Validate(store.Serial); // Reuse the same secret used to decrypt the code password return license.Fields.First(item => item.Name == source).Value.Decrypt("!sEcr3tp@sswOrD!"); }

Die Methode GetEncryptedCodePassword dient als Einstiegspunkt, um das Passwort des verschlüsselten Codes abzurufen. Sie ruft die Methode EncryptedGetEncryptedCodePassword auf und übergibt einen Quellwert als Parameter. Diese Methode liest das Passwort des verschlüsselten Codes, das zur angegebenen Quelle gehört, aus der Lizenz. Mehr über verschlüsselten Code mit einem Passwort erfahren Sie unter Codeverschlüsselung im Handbuch von Babel Obfuscator.

In EncryptedGetEncryptedCodePassword laufen die folgenden Schritte ab:

  1. Der Code liest die Seriennummer der Lizenz und den zugehörigen öffentlichen Schlüssel aus der Lizenzdatei.
  2. Der öffentliche Schlüssel wird mit dem Passwort „pk_p@sswOrd“ entschlüsselt.
  3. Eine Instanz von StringLicenseManager wird erstellt, um die Lizenz mit dem entschlüsselten öffentlichen Schlüssel zu validieren.
  4. Die Lizenz wird validiert, indem die Seriennummer an die Methode Validate des Managers übergeben wird.
  5. Ist die Seriennummer gültig und erfüllt sie alle Lizenzeinschränkungen, wird ein Lizenzobjekt zurückgegeben.
  6. Das Passwort des verschlüsselten Codes, das zur angegebenen Quelle gehört, wird aus den Feldern der Lizenz gelesen.
  7. Zum Schluss wird das verschlüsselte Passwort mit dem Geheimnis „!sEcr3tp@sswOrD!“ entschlüsselt und zurückgegeben.

Außerdem wird der Code mit Babel Obfuscator verschleiert und verschlüsselt. Die folgenden Verschleierungsfunktionen werden verwendet:

  1. Für die Methode ExecuteEncryptedCode:
[Obfuscation(Feature = "msil encryption:source=source1;password=p@ssw0rd1;internal=true", Exclude = false)] private void ExecuteEncryptedCode() { Console.WriteLine("Encrypted code running"); }

Die Funktion msil encryption wird mit der angegebenen Quelle („source1“), dem Verschlüsselungspasswort („p@ssw0rd1“) und internal auf true angewendet. Diese Verschleierung stellt sicher, dass der Code in dieser Methode verschlüsselt und geschützt ist.

Im Zusammenspiel dieser Komponenten wird das Passwort des verschlüsselten Codes aus der Lizenz abgerufen. Mit dem validierten Passwort wird der verschlüsselte Code in der Methode ExecuteEncryptedCode entschlüsselt und ausgeführt. So entsteht eine sichere und kontrollierte Ausführungsumgebung für sensible Codeabschnitte.

Last updated on