org - Licencia para la aplicación de escritorio C#
mapwindows 5 (5)
¿Cómo puedo agregar licencia a mi aplicación de escritorio C #? Necesito encontrar un método gratuito adecuado para evitar que usuarios no autorizados instalen mi software.
Existen muchos sistemas de administración de licencias para .NET (incluso hay uno integrado para los controles de licencias ). Una rápida búsqueda en Google de ".NET license manager" lanzó el sistema Open License , que es gratuito.
Espero que puedas encontrar más fácilmente.
Probablemente llegue 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 de C #, y me gustaría compartir mis resultados.
Parece que puede crear su propio sistema de licencias bastante seguro utilizando RSA de forma razonablemente fácil.
Obviamente, nada es a prueba de balas cuando se trata de proteger software (es como proteger su casa de los ladrones: las alarmas, los perros que ladran y las cercas lo hacen más problemático de lo que vale, pero no detendrán a alguien determinado a entrar)
Por lo tanto, hacer que sea más problemático de lo que vale la pena es la frase clave en la protección del software: si está ofreciendo un sistema ERP de $ 1,000,000, querrá tener una protección realmente buena autorizada a través de un servicio web (y los usuarios pagan tanto por un sistema no tendría ningún problema en permitir que el sistema tenga acceso constante a Internet)
Sin embargo, si está cobrando solo $ 5 a $ 30 por una aplicación pequeña, los usuarios no van a tolerar una autorización de mano muy pesada.
Creo que el sistema más sencillo 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 invalida la firma digital.
La firma digital se puede obtener de la clase DSACryptoServiceProvider, usando el método SignData.
Se requiere una clave privada para firmar los datos, y la parte pública de esa clave se puede usar para validar la firma: (por lo tanto, la clave debe poder acceder a la clave pública)
El DSAXCryptoServiceProvider tiene métodos para crear y usar claves:
DSACryptoServiceProvider.ToXMLString (bool includePrivate);
devuelve las claves públicas o públicas y privadas actualmente en el proveedor de servicios como una cadena XML.
DSACryptoServiceProvider.FromXMLString (String xmlString)
Este método configura un nuevo DSACryptoServiceProvider con claves privadas o públicas existentes obtenidas de DSACryptoServiceProvider.ToXMLString ()
La única falla 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 solucionar mediante la firma adicional de un recurso requerido para la aplicación (como un .dll que contiene la lógica esencial para la aplicación, o incluso el mismo .exe); por lo tanto, si se cambia la clave pública, esta firma adicional (oculta) convertirse en inválido
Otras formas de mejorar esto incluyen ocultar los términos de la licencia (serializar una estructura de datos que contenga los términos de la licencia usando el formateador binario a una matriz de bytes, luego usar Convert.ToBase64String () ocultará los términos de la licencia, e incluso si el usuario fue capaz de reemplazar la clave pública que todavía necesitarían para resolver 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:
/// <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)
};
}
Método de verificación:
/// <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 la 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!");
}
}
}
Tenga cuidado con el esfuerzo que realiza para proteger su aplicación; puede ser una pérdida de tiempo si se rompe fácilmente o no se pone a los usuarios si es muy fuerte (por ejemplo, tener que ingresar una contraseña cada vez que se ejecuta).
Puede encontrar un artículo interesante sobre protección de software (de juegos) aquí: http://www.positech.co.uk/talkingtopirates.html
Un enfoque es rodar su propio sistema de verificación de clave parcial . Hay una versión de VB.NET disponible en Code Project:
Utilizamos Eziriz .NET Reactor para ofuscar y licenciar nuestro software comercial. Es bastante bueno y no es tan caro.
(No tengo ninguna afiliación con eziriz en absoluto, solo soy un cliente satisfecho)
Edit: lo siento, vi la palabra ''gratis'' demasiado tarde