infosolutions - login encriptado c#
¿Un método efectivo para encriptar un archivo de licencia? (9)
¿Por qué necesitarías encriptarlo? Si se trata de una alteración, tiene miedo (por ejemplo, que alguien aumente la cantidad de usuarios), ¿podría simplemente firmarla con, por ejemplo, el certificado digital de su organización?
Para una aplicación web, me gustaría crear un sistema de licencia simple pero efectivo. En C #, esto es un poco difícil, ya que mi método de descifrado podría ser visto por cualquier persona que tenga instalado Reflector.
¿Cuáles son algunos métodos para cifrar archivos en C # que son bastante inviolables?
Cuando implemente su código de firma / verificación, tenga cuidado de no colocarlo en un ensamblaje por separado. La seguridad a prueba de manipulaciones de Code Access ahora es muy fácil de evitar, como se explica en el artículo CAS Tamper-Proofing está roto: Consecuencias para las licencias de software .
Descargo de responsabilidad y tapón obligatorios: la compañía que cofundé produce la solución de licencia OffByZero Cobalt .
La única forma de proporcionar algún tipo de seguridad con la licencia es forzar un inicio de sesión en línea contra las credenciales que mantiene usted mismo (muy abstracto).
Todos los otros métodos requieren más tiempo, y por lo tanto más dinero, para implementar, en cuanto a descifrar y abusar de su software en lugar de comprar una licencia.
.NET tiene algunas buenas clases criptográficas, pero como mencionó, si está codificando la descripción de la licencia, todos pueden descompilarla fácilmente.
La respuesta de Wolfwyrd es excelente, pero solo quería ofrecer una versión más simple del método GetPublicKeyFromAssembly de GetPublicKeyFromAssembly (que utiliza muchos métodos auxiliares de la biblioteca que Wolfwyrd proporcionó graciosamente).
En esta versión, este es todo el código que necesita:
/// <summary>
/// Extracts an RSA public key from a signed assembly
/// </summary>
/// <param name="assembly">Signed assembly to extract the key from</param>
/// <returns>RSA Crypto Service Provider initialised with the public key from the assembly</returns>
private RSACryptoServiceProvider GetPublicKeyFromAssembly(Assembly assembly)
{
// Extract public key - note that public key stored in assembly has an extra 3 headers
// (12 bytes) at the front that are not part of a CAPI public key blob, so they must be removed
byte[] rawPublicKeyData = assembly.GetName().GetPublicKey();
int extraHeadersLen = 12;
int bytesToRead = rawPublicKeyData.Length - extraHeadersLen;
byte[] publicKeyData = new byte[bytesToRead];
Buffer.BlockCopy(rawPublicKeyData, extraHeadersLen, publicKeyData, 0, bytesToRead);
RSACryptoServiceProvider publicKey = new RSACryptoServiceProvider();
publicKey.ImportCspBlob(publicKeyData);
return publicKey;
}
Parece que las muestras de MSDN usan parámetros predeterminados y esto da como resultado la firma específica de la máquina, de modo que no puede iniciar sesión en una máquina y verificar en otra máquina arbitraria. Modifiqué la lógica en esas muestras para usar las claves en mi snk en la máquina de firma y las claves de mi ensamblaje en la máquina de verificación. Esto se hizo usando la lógica de la muestra y las rutinas de MSDN en el ejemplo (muy bien hecho) de ExcryptionUtils.cs vinculado anteriormente.
Para firmar el archivo, utilicé esto:
RSACryptoServiceProvider rsaKey = EncryptionUtils.GetRSAFromSnkFile(keyFilePath);
Para verificar el archivo, utilicé esto:
RSACryptoServiceProvider rsaKey = EncryptionUtils.GetPublicKeyFromAssembly
(System.Reflection.Assembly.GetExecutingAssembly());
Por cierto: observé que la verificación de firma XML ignora los comentarios XML.
Parece que quiere utilizar la criptografía pública / privada para firmar un token de licencia (un fragmento o archivo XML, por ejemplo) para que pueda detectar la manipulación. La forma más sencilla de manejarlo es hacer los siguientes pasos:
1) Genere un par de llaves para su empresa. Puede hacer esto en la línea de comando de Visual Studio usando la herramienta SN. La sintaxis es:
sn -k c:/keypair.snk
2) Use el par de llaves para nombrar con fuerza (es decir, firmar) su aplicación cliente. Puede configurar esto usando la pestaña de firma en la página de propiedades en su aplicación
3) Cree una licencia para su cliente, esto debe ser un documento XML y fírmelo con su clave privada. Esto implica simplemente calcular una firma digital y los pasos para lograrlo se pueden encontrar en:
http://msdn.microsoft.com/en-us/library/ms229745.aspx
4) En el cliente, al verificar la licencia, carga XmlDocument y usa su clave pública para verificar la firma y comprobar que la licencia no ha sido manipulada. Los detalles sobre cómo hacer esto se pueden encontrar en:
http://msdn.microsoft.com/en-us/library/ms229950.aspx
Para evitar la distribución de claves (es decir, asegurarse de que su cliente esté utilizando la clave pública correcta), puede extraer la clave pública del ensamblado firmado. Asegurándose de que no tiene otra clave para distribuir e incluso si alguien manipula el ensamblado, el .NET Framework morirá con una excepción de seguridad porque el nombre fuerte ya no coincidirá con el ensamblado.
Para extraer la clave pública del ensamblado del cliente, debe usar un código similar a:
/// <summary>
/// Retrieves an RSA public key from a signed assembly
/// </summary>
/// <param name="assembly">Signed assembly to retrieve the key from</param>
/// <returns>RSA Crypto Service Provider initialised with the key from the assembly</returns>
public static RSACryptoServiceProvider GetPublicKeyFromAssembly(Assembly assembly)
{
if (assembly == null)
throw new ArgumentNullException("assembly", "Assembly may not be null");
byte[] pubkey = assembly.GetName().GetPublicKey();
if (pubkey.Length == 0)
throw new ArgumentException("No public key in assembly.");
RSAParameters rsaParams = EncryptionUtils.GetRSAParameters(pubkey);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParams);
return rsa;
}
He subido una clase de muestra con muchas Utilidades de Cifrado útiles en Snipt en: http://snipt.net/Wolfwyrd/encryption-utilities/ para ayudarte a seguir tu camino.
También incluí un programa de ejemplo en: https://snipt.net/Wolfwyrd/sign-and-verify-example/ . El ejemplo requiere que lo agregue a una solución con la biblioteca de utilidades de cifrado y proporcione un archivo XML de prueba y un archivo SNK para la firma. El proyecto debe configurarse para que se firme con el SNK que genere. Demuestra cómo firmar el archivo XML de prueba utilizando una clave privada del SNK y luego verificar desde la clave pública en el ensamblado.
Actualizar
Se agregó una publicación de blog actualizada con una buena ejecución detallada en los archivos de licencia
RE: No incluya toda la clave en su código. Use sn -p para extraer la parte pública de un archivo. Use eso en su código que distribuye para verificar la licencia.
Usando el código de los artículos de MSDN, creé una aplicación pequeña (LicMaker) para facilitar esto. La aplicación está firmada con el par de claves completo. La entrada es un archivo de licencia .XML sin firmar. El resultado es la firma XML + original en un archivo .LIC firmado. Mi producto también está firmado por el mismo archivo de par de claves completo. El producto verifica que el archivo .LIC no ha sido manipulado. Funciona genial. No usé sn -p para esta solución.
Use un archivo XML firmado. Firma con la parte de clave privada de un par de llaves y compruébalo con la parte de clave pública en tu software. Esto le da la oportunidad de verificar si la licencia ha sido modificada y también verificar si el archivo de licencia es válido.
La firma y comprobación de un archivo XML firmado está documentada en MSDN.
Por supuesto, es lógico que firme el archivo de licencia en su propia empresa y envíe el archivo de licencia al cliente, que luego coloca el archivo de licencia en una carpeta para que lo lea.
Por supuesto, las personas pueden cortar / piratear su ensamblaje distribuido y arrancar la comprobación del signo xml, pero nuevamente, siempre podrán hacerlo, sin importar lo que hagan.
o quizás quiera vincular una licencia a una máquina en particular, por ejemplo, generando la clave de licencia basada en el valor de md5 de la unidad c de la pc. entonces su licencia sería específica de la máquina.