Skip to Content
Nueva versión 12 disponible 🎉
LicensingLicencia de prueba con número de serie

Licencia de prueba con número de serie

Las licencias de prueba permiten a los proveedores de software ofrecer a los clientes potenciales versiones de prueba de duración limitada de sus aplicaciones.

Este artículo explica el concepto de licencia de prueba con número de serie y muestra su implementación con una aplicación de consola de ejemplo. El código muestra cómo crear una licencia de prueba que caduca al cabo de cierto número de días y que limita el número de ejecuciones permitidas. Además, muestra el uso de técnicas de cifrado para proteger código sensible que solo se ejecuta si la licencia es válida. Con el modelo de licencia de prueba con número de serie y el código que lo acompaña, los desarrolladores pueden ver cómo usar Babel Licensing para implementar versiones de prueba de sus productos de software.

Ejemplo de código

Para acceder al código del proyecto TrialLicense y examinarlo con más detalle, puede clonar el repositorio de GitHub con el comando siguiente:

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

El proyecto TrialLicense muestra cómo implementar un sistema de licencias de prueba con Babel Licensing en una aplicación de consola. Este proyecto de ejemplo es compatible con Windows, Linux y macOS. Al clonar el repositorio tendrá acceso al código fuente completo, lo que le permitirá profundizar en los detalles de la implementación, examinar los distintos componentes y explorar las funcionalidades del sistema de licencias de prueba.

El proyecto usa el paquete NuGet de Babel Obfuscator para ofuscar y cifrar el código durante el proceso de compilación.

Para activar Babel Obfuscator, establezca la variable de entorno BABEL_LICENSE en la ruta del archivo de licencia o en la clave de licencia flotante.

El código cifrado solo se puede ejecutar con un número de serie válido que contenga la contraseña de descifrado.

Ejemplo de licencia de prueba

Para iniciar la aplicación, abra una ventana de shell, vaya a la carpeta Debug del proyecto y ejecute el comando TrialLicense pulsando ENTER. La aplicación se ejecutará.

Generación de la licencia de prueba

El código siguiente se encarga de generar el número de serie de una licencia de prueba:

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");

Este es el desglose de lo que hace:

  1. HardwareId.Create().ToMachineKey() genera una clave específica del hardware que identifica de forma única el equipo actual. Esta clave se usa para vincular la licencia de prueba al equipo actual.
  2. (RSASignature)Pem.ReadSignature("Keys.pem") lee la clave privada RSA del archivo «Keys.pem». Esta clave se usa para firmar la licencia y validar su autenticidad.
  3. new StringLicense() crea una instancia nueva de la clase StringLicense, que representa la licencia de prueba.
  4. .ForAssembly(Assembly.GetExecutingAssembly()) especifica que la licencia está asociada al ensamblado actual.
  5. .WithUniqueId() genera un identificador único para la licencia.
  6. .WithHardwareKey(hardwareKey) vincula la licencia al equipo actual asociándola a la clave de hardware generada en el punto 1.
  7. .WithTrialDays(2) establece el período de prueba en 2 días, lo que indica que la licencia caducará transcurrido ese plazo.
  8. .WithMaximumRunCount(3) establece el número máximo de ejecuciones permitidas para la versión de prueba.
  9. .WithField("source1", "p@ssw0rd1".Encrypt("!sEcr3tp@sswOrD!")) añade a la licencia un campo llamado «source1» y le asigna como valor una contraseña cifrada. Esta contraseña se usará para descifrar el código concreto que se ejecuta cuando la licencia es válida.
  10. .SignWith(sign) firma la licencia con la clave privada RSA obtenida en el paso 2, lo que garantiza su integridad y autenticidad.
  11. lic.ToReadableString("ASCII") convierte el objeto de licencia en una representación de cadena ASCII.
  12. El número de serie de la licencia resultante se guarda en el registro, junto con la clave pública que se usa para la validación.

Este código muestra el proceso de generación del número de serie de una licencia de prueba, incluida su protección con cifrado y su almacenamiento en el registro. La licencia de prueba se puede validar con la clave pública correspondiente para garantizar su autenticidad y aplicar las restricciones de prueba, como la duración de la prueba y el límite de ejecuciones.

Validación de la licencia de prueba

El fragmento de código siguiente muestra una implementación práctica de este proceso. Usa Babel Licensing para validar el número de serie de prueba.

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); }

Aquí, la clave pública que se usa para validar la firma de la licencia se obtiene de la información del archivo de licencia. Se obtiene el valor asociado a la clave «Key» y se usa la contraseña de descifrado «pk_p@sswOrd» para descifrar el valor guardado.

Se crea una instancia de la clase StringLicenseManager para gestionar el proceso de validación de la licencia. A la propiedad SignatureProvider del gestor se le asigna un objeto RSASignature creado a partir de la clave pública obtenida. Así el gestor queda configurado para usar la clave pública al validar la firma de la licencia.

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

Para validar la licencia se llama al método manager.Validate(serial). El número de serie de la licencia, guardado en la variable serial, se pasa como argumento. Si el número de serie es válido y cumple todas las restricciones de la licencia, se devuelve un objeto de licencia que implementa la interfaz Babel.Licensing.ILicense. Este objeto representa la licencia validada.

Por último, se muestran en la consola el tiempo de prueba restante y el número de ejecuciones que quedan.

En conjunto, este código valida el número de serie de una licencia obteniendo del registro el número de serie y la clave pública, configurando el gestor de licencias con la clave pública y llamando al método de validación. Después muestra el resultado de la validación y la información pertinente de la licencia, como el tiempo de prueba y el número de ejecuciones, si procede.

Ejecución del código cifrado

Este fragmento de código muestra la ejecución del código cifrado y cómo se puede obtener con Babel Obfuscator. A continuación se examina cómo funciona:

En primer lugar, intervienen dos métodos:

[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!"); }

El método GetEncryptedCodePassword sirve de punto de entrada para obtener la contraseña del código cifrado. Llama al método EncryptedGetEncryptedCodePassword y le pasa como parámetro un valor de origen. La finalidad de este método es extraer de la licencia la contraseña del código cifrado asociada al origen indicado. Consulte el Cifrado de código de Babel Obfuscator para saber más sobre el código cifrado con contraseña.

Dentro de EncryptedGetEncryptedCodePassword se dan los pasos siguientes:

  1. El código obtiene del archivo de licencia el número de serie de la licencia y la clave pública correspondiente.
  2. La clave pública se descifra con la contraseña «pk_p@sswOrd».
  3. Se crea una instancia de StringLicenseManager para validar la licencia con la clave pública descifrada.
  4. La licencia se valida pasando el número de serie al método Validate del gestor.
  5. Si el número de serie es válido y cumple todas las restricciones de la licencia, se devuelve un objeto de licencia.
  6. La contraseña del código cifrado asociada al origen especificado se obtiene de los campos de la licencia.
  7. Por último, la contraseña cifrada se descifra con el secreto «!sEcr3tp@sswOrD!» y se devuelve.

Además, se usa Babel Obfuscator para ofuscar y cifrar el código. Las funciones de ofuscación que se usan son:

  1. Para el método ExecuteEncryptedCode:
[Obfuscation(Feature = "msil encryption:source=source1;password=p@ssw0rd1;internal=true", Exclude = false)] private void ExecuteEncryptedCode() { Console.WriteLine("Encrypted code running"); }

Se aplica la función msil encryption con el origen especificado («source1»), la contraseña de cifrado («p@ssw0rd1») e internal establecido en true. Esta ofuscación garantiza que el código de este método quede cifrado y protegido.

Al combinar estos componentes, la contraseña del código cifrado se puede obtener de la licencia con Babel Obfuscator. La contraseña validada permite descifrar y ejecutar el código cifrado del método ExecuteEncryptedCode, lo que proporciona un entorno de ejecución seguro y controlado para las secciones de código sensibles.

Last updated on