etiquetas - taglib java
¿Ofusca su código comercial de Java? (7)
Me pregunto si alguien usa ofuscadores java comerciales / gratuitos en su propio producto comercial. Solo conozco un proyecto que realmente tuvo un paso ofuscante en el paso de compilación de Ant para versiones.
¿Te ofuscas? Y si es así, ¿por qué te ofuscas?
¿Es realmente una forma de proteger el código o es solo una mejor sensación para los desarrolladores / gerentes?
editar: Ok, para ser exactos sobre mi punto: ¿se ofusca para proteger su IP (sus algoritmos, el trabajo que ha puesto en su producto)? No me ofuscaré por razones de seguridad, eso no se siente bien. Así que solo estoy hablando de proteger el código de sus aplicaciones contra la competencia.
@staffan tiene un buen punto:
La razón para mantenerse alejado del flujo de código de encadenamiento es que algunos de esos cambios hacen que sea imposible para la JVM optimizar de manera eficiente el código. De hecho, en realidad degradará el rendimiento de su aplicación.
Creo que la antigua (clásica) forma de la ofuscación está perdiendo gradualmente su relevancia. Porque en la mayoría de los casos, un ofuscador clásico rompe un rastro de pila (no es bueno para apoyar a sus clientes)
Hoy en día, el punto principal es no proteger algunos algoritmos, sino proteger datos confidenciales: inicios de sesión / contraseñas / claves de API, código responsable de licencias (piratería aún aquí, especialmente Europa Occidental, Rusia, Asia, mi humilde opinión), identificaciones de cuentas publicitarias, etc. .
Dato interesante: tenemos todos estos datos confidenciales en Strings. En realidad, Strings es aproximadamente el 50-80% de la lógica de nuestras aplicaciones. Me parece que el futuro de la ofuscación es "Herramientas de cifrado de cadenas".
Pero ahora la característica de "cifrado de cadenas" está disponible solo en ofuscadores comerciales, como: Allatori , Zelix KlassMaster , Smokescreen , Stringer Java Obfuscation Toolkit , DashO .
NB Soy CEO en Licel LLC. Desarrollador de Stringer Java Obfuscator.
Creo que, en su mayor parte, la ofuscación no tiene sentido: incluso con el código fuente completo, en general es bastante difícil determinar cuál fue la intención (suponiendo que no hay comentarios ni nombres significativos para las variables locales, que es el caso cuando -generar fuentes del código de bytes). La ofuscación simplemente decora el pastel.
Creo que los desarrolladores y especialmente sus gerentes tienden a exagerar demasiado el riesgo de que alguien vea el código fuente. Si bien los decompiladores buenos pueden producir un código fuente atractivo, no es trivial trabajar con él, y los costos asociados (sin mencionar los riesgos legales) son lo suficientemente altos como para que este enfoque rara vez sea útil. Solo me he descompilado para depurar problemas con productos de proveedores de código cerrado (bloqueos en la capa de abstracción de DB, ugh). Bytecode en realidad estaba ofuscado, creo, pero aún así encontramos el problema subyacente: era un problema de diseño real.
Pasé algún tiempo este año probando varios ofuscadores de Java, y encontré uno que está muy por delante del resto: JBCO . Desafortunadamente es un poco engorroso de configurar, y no tiene GUI, pero en términos del nivel de ofuscación que produce, no tiene paralelo. Intenta alimentarlo con un bucle simple, y si su descompilador no falla al intentar cargarlo, verá algo como esto:
if(i < ll1) goto _L6; else goto _L5
_L5:
char ac[] = run(stop(lI1l));
l7 = (long)ac.length << 32 & 0xffffffff00000000L ^ l7 & 0xffffffffL;
if((int)((l7 & 0xffffffff00000000L) >> 32) != $5$)
{
l = (long)III << 50 & 0x4000000000000L ^ l & 0xfffbffffffffffffL;
} else
{
for(l3 = (long)III & 0xffffffffL ^ l3 & 0xffffffff00000000L; (int)(l3 & 0xffffffffL) < ll1; l3 = (long)(S$$ + (int)(l3 & 0xffffffffL)) ^ l3 & 0xffffffff00000000L)
{
for(int j = III; j < ll1; j++)
{
l2 = (long)actionevent[j][(int)(l3 & 0xffffffffL)] & 65535L ^ l2 & 0xffffffffffff0000L;
l6 = (long)(j << -351) & 0xffffffffL ^ l6 & 0xffffffff00000000L;
l1 = (long)((int)(l6 & 0xffffffffL) + j) & 0xffffffffL ^ l1 & 0xffffffff00000000L;
l = (long)((int)(l1 & 0xffffffffL) + (int)(l3 & 0xffffffffL)) << 16 & 0xffffffff0000L ^ l & 0xffff00000000ffffL;
l = (long)ac[(int)((l & 0xffffffff0000L) >> 16)] & 65535L ^ l & 0xffffffffffff0000L;
if((char)(int)(l2 & 65535L) != (char)(int)(l & 65535L))
{
l = (long)III << 50 & 0x4000000000000L ^ l & 0xfffbffffffffffffL;
}
}
}
}
¿No sabías que Java tenía goto''s? Bueno, la JVM los admite =)
Si se ofusca, manténgase alejado de ofuscadores que modifiquen el código cambiando el flujo de código y / o agregando bloques de excepción y tal que dificulten el desmontaje. Para que el código sea ilegible, por lo general basta con cambiar todos los nombres de los métodos, campos y clases.
La razón para mantenerse alejado del cambio de flujo de código es que algunos de esos cambios hacen que sea imposible para la JVM optimizar de manera eficiente el código. De hecho, en realidad degradará el rendimiento de su aplicación.
Supongo que realmente se trata de para qué es tu código Java, cómo se distribuye y quiénes son tus clientes. No ofuscamos nada, ya que nunca hemos encontrado uno que sea particularmente bueno y que tiende a ser más problemático de lo que vale. Si alguien tiene acceso a nuestros archivos JAR y tiene el conocimiento para poder husmear dentro de ellos, entonces hay cosas mucho más preocupantes que pueden hacer que robar nuestro código fuente.
Yo uso ProGuard y lo recomiendo encarecidamente. Si bien la ofuscación protege su código de atacantes casuales, su principal beneficio es el efecto minimizador de eliminar las clases y métodos no utilizados y acortar todos los identificadores a 1 o 2 caracteres.
Yo uso Proguard para el desarrollo de JavaME. No solo es muy bueno para hacer que los archivos jar sean más pequeños (Esencial para dispositivos móviles), sino que también es útil como una forma más agradable de hacer un código específico del dispositivo sin recurrir a herramientas de preprocesamiento poco amigables con IDE, como la antena.
P.ej
public void doSomething()
{
/* Generated config class containing static finals: */
if (Configuration.ISMOTOROLA)
{
System.out.println("This is a motorola phone");
}
else
{
System.out.println("This is not a motorola phone");
}
}
Esto se compila, se ofusca y el archivo de clase termina como si hubiera escrito:
public void doSomething()
{
System.out.println("This is a motorola phone");
}
De modo que puede tener variantes de código para solucionar los errores del fabricante en las implementaciones de JVM / biblioteca sin agrupar los archivos finales de la clase ejecutable.
Creo que algunos ofuscadores comerciales también pueden fusionar archivos de clase en ciertos casos. Esto es útil porque cuantas más clases tenga, mayor será la sobrecarga de tamaño que tenga en el archivo zip (jar).