2011-01-06 16 views
6

Estoy en la fase de requisitos para crear una aplicación Java EE que probablemente se ejecutará en un backend GlassFish/JBoss (no importa por ahora). I saber No debería estar pensando en la arquitectura en el momento de las necesidades, pero uno no puede evitar imaginarse cómo se unirían todos los componentes :-)Java Client .class File Protection

Estos son algunos requisitos duros y no flexibles sobre del lado del cliente:
(1) La aplicación del cliente será un cuadro Swing
(2) El cliente puede descargarse libremente, pero utilizará un modelo de suscripción (por lo que requiere un mecanismo de inicio de sesión con autenticación/autorización del lado del servidor , etc.)
(3) Sí, Java es la mejor solución de plataforma para el problema en cuestión f o por razones fuera del alcance de este post
(4) La Archivos del lado del cliente .class es necesario salvaguardar contra la descompilación

Esa última (cuarta) requisito es la base de este post.

No estoy realmente preocupado por alguien descompilando realmente y obteniendo mi código fuente: al final, son solo controles Swing impulsados ​​por una lógica de negocios liviana.

Me preocupa una situación en la que alguien descompile mi código, lo modifique para explotarlo/atacarlo, volver a compilarlo y activarlo.

He previsto todo tipo de soluciones desagradables, pero no sabía si esto era un problema común con una solución común para los desarrolladores de Java EE. ¿Alguna idea?

¡No estoy interesado en las técnicas de "código de ofuscación"!

¡Gracias por cualquier entrada!

+0

En realidad, no entiendo ... ¿Si la autenticación y la autorización se producen en el lado del servidor que lo que podría hacer un cliente malintencionado? – Rekin

+0

No olvide que en un entorno de red, "el malo" puede ponerle un rastreador y averiguar qué se envía también. – Suirtimed

+0

@Suirtmed: Lo mismo ocurre con cualquier aplicación de cliente de navegador web. La solución es simple: use la comunicación encriptada (SSL). Básicamente, no puedo encontrar ninguna razón para justificar el cifrado de código. – Rekin

Respuesta

5

Estoy aquí para traerte las malas noticias. No puedes detener esto.

Cavé en esto profundamente una vez. En los niveles más bajos de la JVM, el Classloader debe obtener un flujo de bytes no encriptado que es el archivo de clase. No puede cambiar eso menos que reemplazar la JVM con su propio código. Además, hay un gancho que permite ver el flujo de bytes (copiado, etc.). No importa lo que haga en niveles superiores, la JVM siempre llegará a este punto y permitirá el acceso a su archivo de clase. Una vez que se obtiene el archivo de clase, se puede descompilar. Las técnicas y herramientas de ofuscación pueden disminuirlo o dificultarlo, pero tampoco pueden detenerlo.

Le sugiero encarecidamente que proteja su servidor utilizando métodos de seguridad comprobados y verdaderos. No incruste la salsa secreta en algo que le dé al cliente. Lo conseguirán de alguna manera si están lo suficientemente determinados.

+1

+1. Exactamente. Probablemente has oído hablar de romper el algoritmo de comunicación de Skype. La seguridad por oscuridad no es seguridad. – Rekin

+0

es una buena publicación y verdadera. Siempre construya sus servidores de forma segura y robusta pudiendo tratar con cualquier contenido que provenga del cable. – bestsss

3

Veo esto como un problema común de criptografía "fuerte v. Débil": si el conocimiento del algoritmo es suficiente para comprometer el mensaje (es decir, su inicio de sesión), la criptografía es débil.

¿Qué tal si utilizas algo como OAuth? A través de un proceso de autenticación de una sola vez con el servidor, la aplicación del cliente recibe tokens, y el servidor siempre puede revocar la autorización para cualquier cliente si es necesario.

También tenga en cuenta que la autenticación no sustituye a la autorización. El hecho de que su sistema crea que sabe quién es alguien no significa que deba estar autorizado para hacer lo que quiera. También deberá implementar un buen control de acceso, como JAAS o Spring Security, y vincularlo a la autenticación. El primer control de cualquier llamada del cliente es para la autenticación, el segundo es si ese cliente en particular está autorizado a realizar la llamada en primer lugar.

Independientemente de lo que haga, su servidor solo debe permitir llamadas en función de la autorización otorgada a un usuario.

9

Debe suponer que el código SE descompilará y se usará para explotar/atacar el servidor.

Solo confíe en lo que hace el servidor.

+3

Solo para agregar: @Zac: su preocupación debe estar en ** cómo ** autentica a sus usuarios en el servidor, ya que teóricamente un atacante no necesita su aplicación para causar daño. – Jeremy

1

Utilice una autenticación decente del servidor, no almacene nombres de usuario, contraseñas o claves de cifrado en la aplicación, y luego, como comentarios Rekin, no veo qué en su código puede traicionar la protección del servidor.

Si absolutamente necesita encriptar las comunicaciones (no parece un requisito) use SSL o cualquier criptografía de clave pública.

0

he un "pensar fuera de la caja" solución para el punto número 4.

Estoy asumiendo su aplicación tiene acceso a la red, ya que va en línea para autenticar ...

  1. Usted tiene una archivos agrupados o "jar" con clases en ellos. La única diferencia es que las clases se cifran utilizando una clave simétrica.
  2. Cuando se inicia la aplicación, la aplicación se autentica en línea y obtiene la clave a través de una conexión segura (por ejemplo, SSL).
  3. A continuación, carga todos los archivos cifrados en la memoria y los descifra.
  4. A continuación, cree un cargador de clases personalizado y cargue la clase descifrada en el cargador de clases utilizando ClassLoader.defineClass
  5. ¡Ya está listo para empezar!

Este no es un método no concreto de hacer las cosas y como he dicho está fuera de la caja. Pero hace que sea un poco más difícil robar tu código. Pero como han dicho los otros carteles, no puede ocultar secretos en su código que está en el lado del cliente.

+0

Por favor vea mi respuesta arriba. Investigué exactamente esto. Desafortunadamente no te protege. Su cargador de clases personalizado debe pasar el control en algún momento a un cargador de clases concreto que se proporciona con la JVM. El gancho está siempre allí, después del descifrado. – rfeak

+0

@rfeak - 100% de acuerdo con usted. – Paul