2010-03-10 14 views
6

¿Qué tan difícil sería recuperar recursos incrustados desde una aplicación .NET, desde fuera de la aplicación en sí? Incluso si los recursos están comprimidos y trivialmente encriptados, ¿qué tan difícil es recuperarlos usando una herramienta? (No estoy preocupado con la protección de los datos en sí, sólo los métodos de recuperación del recurso mismo)¿Qué tan seguros son los recursos en .NET?


EDIT:

Creo que mi pregunta fue mal entendido, era menos de la encriptación y más sobre la recuperación, que no sea reflector, ¿qué más se puede usar?

+2

¿Encriptado cómo, exactamente? –

+0

Muchas herramientas pueden hacer esto. ILSpy puede hacerlo, por ejemplo. Los recursos son fácilmente recuperables. Y el método de descifrado que usa internamente en el ensamblado .NET se puede revertir fácilmente. – BrainSlugs83

Respuesta

8

Es trivial recuperar recursos de una DLL compilada .NET usando herramientas como .NET Reflector o .NET Resourcer.

+0

¿Hay alguna otra forma que conozcas? Voy a probar Resourcer, pero Reflector no es un problema actualmente. –

+2

Bueno, podrías escribir un poquito de código. Assembly.GetManifestResourceStream(). –

+0

Además, intente abrir el ensamblado en Visual Studio. Solo curiosidad, ¿encontraste que Reflector no puede extraerlos? –

6

Si encriptas los recursos con una clave que está incorporada en la aplicación, entonces será fácil recuperar la clave y, por lo tanto, los recursos, con un poco de ingeniería inversa.

Si las encriptas usando un algoritmo seguro y le pides al usuario que ingrese la contraseña, entonces sin la contraseña no será posible extraer los recursos. Pero supongo que eso no es lo que quieres. Supongo que quiere evitar que el usuario use sus recursos fuera de la aplicación.

En caso afirmativo, la respuesta corta es: los recursos en .NET no son seguros.

+3

Te he subido; Sin embargo, los recursos en CUALQUIER COSA no son seguros. No importa qué idioma utilice, si la clave de cifrado está incrustada en la aplicación, se puede extraer. – NotMe

2

Si le muestro una caja fuerte con un millón de dólares en ella, entonces aléjese, eventualmente se meterá en esa caja fuerte. No hay tecnología que proteja ese dinero, tu única barrera real es el tiempo.

Es lo mismo para el software. La única manera de proteger los recursos es no colocarlos donde alguien pueda, con el tiempo suficiente, llegar a ellos. La opción más efectiva que conozco es almacenar los recursos críticos en un servidor que controlas.

Por supuesto, muchas personas lo hacen mal. De una forma u otra, permiten que el recurso seguro se copie temporalmente en la computadora del usuario. En ese punto, el juego se pierde. Esto significa que solo puede asegurar realmente recursos que tienen un clon natualmente temporal. Por ejemplo, un token de seguridad que caduca o los resultados de un cálculo que no revelan cómo se realizó el cálculo.

2

El problema es menos sobre los recursos de .NET y más sobre la seguridad en general. Podría reformular la pregunta ya que "la aplicación de mi cliente almacena secretos que no quiero que sean de ingeniería inversa" y no cambien la intención.

¿Qué hay en sus archivos de recursos y por qué necesita protección? ¿Has considerado un diseño en el que no guardas esos secretos en absoluto para el cliente? Si confía en mantener seguros los secretos del lado del cliente, creo que estará decepcionado.

+1

¿Qué tal un archivo de licencia que le permite usar una biblioteca de terceros? - si desea utilizar esa biblioteca de terceros en el cliente, debe poder acceder a ese archivo de licencia, en el cliente, pero no desea que el usuario final pueda extraer el archivo de licencia. y reutilizarlo ellos mismos ... si se filtra, la licencia es revocada. Entonces, ¿cómo lo puedes asegurar? – BrainSlugs83

3

Aquí hay algunos códigos rápidos para obtener recursos de ensamblajes. Usted decide qué tan fácil y seguro es ...

class Program 
{ 
    static void Main(string[] args) 
    { 
     var assemblies = from file in args 
         let assembly = TryLoad(file) 
         where assembly != null 
         from rName in assembly.GetManifestResourceNames() 
         select new { assembly, rName }; 

     foreach (var item in assemblies) 
      using (var rs = item.assembly 
           .GetManifestResourceStream(item.rName)) 
       SaveTo(rs, item.rName); 

    } 

    static void SaveTo(Stream stream, string name) 
    { 
     var buffer = new byte[32*1024]; 
     var bufferLen = 1; 
     using (var fs = new FileStream(name, FileMode.Create)) 
      while (bufferLen > 0) 
       if ((bufferLen = stream.Read(buffer, 0, buffer.Length)) > 0) 
        fs.Write(buffer, 0, bufferLen); 
    } 

    static Assembly TryLoad(string filename) 
    { 
     if (string.IsNullOrEmpty(filename) || 
      !File.Exists(filename)) 
      return null; 
     try 
     { 
      var fullName = Path.GetFullPath(filename); 
      return Assembly.LoadFile(fullName); 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine(ex); 
      return null; 
     } 
    } 
} 
Cuestiones relacionadas