2010-09-02 26 views
22

¿Cómo puedo agregar una licencia a mi aplicación de escritorio C#? Necesito encontrar un método gratuito adecuado para evitar que usuarios no autorizados instalen mi software.Licencia para la aplicación de escritorio C#

+0

¿Qué es exactamente lo que quiere decir con "añadir una licencia"? –

+0

La aplicación debe tener una clave de licencia para su instalación. – Noro

Respuesta

9

Existen muchos sistemas de administración de licencias para .NET (incluso hay uno built-in for licensing controls). Un rápido buscador de Google para ".NET License Manager" lanzó el sistema Open License, que es gratis.

Espero que pueda encontrar más fácilmente.

+2

url para licencia abierta ha cambiado: https://sourceforge.net/projects/net-lic-mgr/ –

0

Tenga cuidado con la cantidad de esfuerzo que puso para la protección de su aplicación; puede ser un desperdicio de tiempo si se rompe fácilmente o si los usuarios no lo usan correctamente si es muy fuerte (por ejemplo, tener que ingresar una contraseña cada vez que se ejecuta).

un interesante artículo sobre la protección del software (de juegos) se puede encontrar aquí: http://www.positech.co.uk/talkingtopirates.html

1

Utilizamos Eziriz .NET Reactor de ofuscación y la concesión de licencias de nuestro software comercial. Es bastante bueno y no es tan caro.

(no tengo ninguna afiliación con Eziriz en absoluto, sólo soy un cliente satisfechos)

Edit: Lo siento, vio la palabra 'libre' demasiado tarde

50

Probablemente estoy un poco tarde, pero pasé un poco de tiempo tratando de encontrar un método rápido y efectivo para asegurar una pequeña aplicación C#, y me gustaría compartir mis resultados.

Parece que usted puede construir su propio sistema de licencias, bastante seguro utilizando RSA razonablemente fácil.

Obviamente, nada es a prueba de balas cuando se trata de proteger el software (es como proteger su casa de los ladrones: las alarmas, los ladridos de perros y las cercas lo convierten en más problemas de lo que vale, pero no detendrán a alguien decidido a en)

Por lo tanto, hacer más problemas de lo que vale es la frase clave en la protección del software: si está ofreciendo un ERP de $ 1,000,000 sistema, desearía tener una muy buena protección que autorizara a través de un servicio web (y los usuarios que paguen por un sistema no tendrían problemas para permitir que el sistema tenga acceso a Internet constante)

Sin embargo, si solo está cargando $ 5- $ 30 por una pequeña aplicación, los usuarios no van a aguantar con una autorización muy pesada.

Creo que el sistema más simple de producir es firmar digitalmente un archivo de licencia que contiene los detalles del producto, el usuario y su duración.

Esto significa que cualquier modificación del archivo de licencia hace que la firma digital válida.

La firma digital se puede obtener de la clase DSACryptoServiceProvider, utilizando el método SignData.

Se requiere una clave privada para firmar los datos, y la parte pública de esa tecla se puede utilizar para validar la firma: (por lo tanto la clave pública debe ser accesible por la aplicación)

El DSAXCryptoServiceProvider tiene métodos para crear y usar claves:

DSACryptoServiceProvider.ToXMLString (bool includePrivate);

devuelve Public or Public & Claves privadas actualmente en el proveedor de servicios como una cadena XML.

DSACryptoServiceProvider.FromXMLString (String xmlString)

Este método establece una nueva DSACryptoServiceProvider con claves privadas o públicas obtenidas de DSACryptoServiceProvider.ToXMLString() existente

El único fallo en la seguridad de este sistema sería la posibilidad de que un usuario interrumpa el suministro de su propia clave pública. Esto les permitiría generar sus propios archivos de licencia desde su propia clave privada.

Esto se puede obtener mediante la firma adicional de un recurso requerido para la aplicación (como un .dll que contiene lógica esencial para la aplicación, o incluso el propio .exe) - por lo tanto, si se cambia la clave pública, esta adicional (oculto) la firma se invalidará.

Otras formas de mejorar esto incluyen oscurecer los términos de licencia (serializar una estructura de datos que contiene los términos de la licencia utilizando el formateador binario en una matriz de bytes, luego usar Convert.ToBase64String() oscurecerá los términos de la licencia, y incluso si el usuario pudiera reemplazar la clave pública, aún necesitaría calcular la representación de los datos)

Tengo un sistema de ejemplo que escribí, pero es demasiado grande para citarlo por completo, pero este es el método CreateLicense de ella:

/// <summary> 
    /// use a private key to generate a secure license file. the private key must match the public key accessible to 
    /// the system validating the license. 
    /// </summary> 
    /// <param name="start">applicable start date for the license file.</param> 
    /// <param name="end">applicable end date for the license file</param> 
    /// <param name="productName">applicable product name</param> 
    /// <param name="userName">user-name</param> 
    /// <param name="privateKey">the private key (in XML form)</param> 
    /// <returns>secure, public license, validated with the public part of the key</returns> 
    public static License CreateLicense(DateTime start, DateTime end, String productName, String userName, String privateKey) 
    { 
     // create the licence terms: 
     LicenseTerms terms = new LicenseTerms() 
     { 
      StartDate = start, 
      EndDate = end, 
      ProductName = productName, 
      UserName = userName 
     }; 

     // create the crypto-service provider: 
     DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); 

     // setup the dsa from the private key: 
     dsa.FromXmlString(privateKey); 

     // get the byte-array of the licence terms: 
     byte[] license = terms.GetLicenseData(); 

     // get the signature: 
     byte[] signature = dsa.SignData(license); 

     // now create the license object: 
     return new License() 
     { 
      LicenseTerms = Convert.ToBase64String(license), 
      Signature = Convert.ToBase64String(signature) 
     }; 
    } 

verificar el método:

/// <summary> 
    /// validate license file and return the license terms. 
    /// </summary> 
    /// <param name="license"></param> 
    /// <param name="publicKey"></param> 
    /// <returns></returns> 
    internal static LicenseTerms GetValidTerms(License license, String publicKey) 
    { 
     // create the crypto-service provider: 
     DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); 

     // setup the provider from the public key: 
     dsa.FromXmlString(publicKey); 

     // get the license terms data: 
     byte[] terms = Convert.FromBase64String(license.LicenseTerms); 

     // get the signature data: 
     byte[] signature = Convert.FromBase64String(license.Signature); 

     // verify that the license-terms match the signature data 
     if (dsa.VerifyData(terms, signature)) 
      return LicenseTerms.FromString(license.LicenseTerms); 
     else 
      throw new SecurityException("Signature Not Verified!"); 
    } 

los términos de licencia Clase:

/// <summary> 
    /// terms of the license agreement: it's not encrypted (but is obscured) 
    /// </summary> 
    [Serializable] 
    internal class LicenseTerms 
    { 
     /// <summary> 
     /// start date of the license agreement. 
     /// </summary> 
     public DateTime StartDate { get; set; } 

     /// <summary> 
     /// registered user name for the license agreement. 
     /// </summary> 
     public String UserName { get; set; } 

     /// <summary> 
     /// the assembly name of the product that is licensed. 
     /// </summary> 
     public String ProductName { get; set; } 

     /// <summary> 
     /// the last date on which the software can be used on this license. 
     /// </summary> 
     public DateTime EndDate { get; set; } 

     /// <summary> 
     /// returns the license terms as an obscure (not human readable) string. 
     /// </summary> 
     /// <returns></returns> 
     public String GetLicenseString() 
     { 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       // create a binary formatter: 
       BinaryFormatter bnfmt = new BinaryFormatter(); 

       // serialize the data to the memory-steam; 
       bnfmt.Serialize(ms, this); 

       // return a base64 string representation of the binary data: 
       return Convert.ToBase64String(ms.GetBuffer()); 

      } 
     } 

     /// <summary> 
     /// returns a binary representation of the license terms. 
     /// </summary> 
     /// <returns></returns> 
     public byte[] GetLicenseData() 
     { 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       // create a binary formatter: 
       BinaryFormatter bnfmt = new BinaryFormatter(); 

       // serialize the data to the memory-steam; 
       bnfmt.Serialize(ms, this); 

       // return a base64 string representation of the binary data: 
       return ms.GetBuffer(); 

      } 
     } 

     /// <summary> 
     /// create a new license-terms object from a string-representation of the binary 
     /// serialization of the licence-terms. 
     /// </summary> 
     /// <param name="licenseTerms"></param> 
     /// <returns></returns> 
     internal static LicenseTerms FromString(String licenseTerms) 
     { 

      using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(licenseTerms))) 
      { 
       // create a binary formatter: 
       BinaryFormatter bnfmt = new BinaryFormatter(); 

       // serialize the data to the memory-steam; 
       object value = bnfmt.Deserialize(ms); 

       if (value is LicenseTerms) 
        return (LicenseTerms)value; 
       else 
        throw new ApplicationException("Invalid Type!"); 

      } 
     } 

    } 
+0

Cosas geniales. ¡Gracias! –

+0

awesome, tks ... –

+0

Supongo que si codifica la estructura de datos, como darle atributos completamente irrelevantes que parezcan relevantes y hacer los atributos relevantes de alguna manera calculables a partir de algunos atributos aparentemente irrelevantes, serializarlo y codificarlo en base64, debe ser ** realmente ** es difícil de entender cómo funciona el sistema –

Cuestiones relacionadas