Fonte: http://erkobridee.com/2008/06/19/protegendo-o-seu-cdigo-java-da-engenharia-reversa/
Publicado por Erko Bridee em 19/06/2008 18:02 pm | sobre: Desenvolvimento, JAVA, Segurança, Tutorial, tilidade

Caso você seja um desenvolvedor de aplicações java, é importante compreender que os arquivos binários .class do Java podem ser facilmente descompilados em uma engenharia reversa. Neste post iremos ver como um arquivo .class Java é revertido para um fonte Java e como proteger o seu código disto.
O código fonte java é compilado para um arquivo ,class, o qual possui o código binário. A máquina virtual Java (JVM) precisa apenas desse arquivo para executar a sua aplicação. O problema é que este arquivo .class pode ser facilmente descompilado, recuperando o seu código fonte original, utilizando alguma ferramenta para descompilação do .class e caso você procure no Google irá perceber que não é dificil encontrar uma ferramenta para fazer exatamente isto.
A melhor solução para previnir a engenharia reversa é ofuscar o nosso arquivo .class, o que irá dificultar e muito a engenharia versa. De acordo com o dicionário ofuscar que dizer “tornar algo obscuro, não compreensível“. E é exatamente isto o que muitas ferramentas de ofuscar faz, como será explicado a seguir.
Descompilando um arquivo .class Java
Antes de compreender como um ofuscar um código java, vamos tentar compreender como alguem consegue realziar uma engenharia reversa da sua aplicação java. A seguir 3 passos para explicar como um arquivo .class é recuperado desse o código fonte java original, usando técnicas de engenharia reversa.
1. Crie um HelloWorld.java como o código abaixo:
- public class HelloWorld {
- public static void main (String args[]) {
- String userMessage = “Hello World!”;
- int userCount = 100;
- userCount = userCount + 1;
- System.out.println(userMessage);
- System.out.println(userCount);
- }
- }
2. Compile o programa HelloWorld.java e execute, algo como o feito a seguir:
$ javac HelloWorld.java
$ java HelloWorld
Hello World!
101
O arquivo Java .class contém apenas o byte code. caso você tente ver o conteúdo do arquivo .class, irá notar que é algo que humanamente não é compreensível, como o que é mostrado abaixo:
$ vi HelloWorld.class
Ãþº¾^@^@^@2^@
^@^G^@^P^H^@^Q ^@^R^@^S
^@^T^@^V^G^@^W^G^@^X^A^@^F<init>^A^@^C()V^A^@^DCode^A^@^OLineNumberTable
^A^@^Dmain^A^@^V([Ljava/lang/String;)V^A^@
SourceFile^A^@^OHelloWorld.java^L^@^H^@ ^A^@^LHello World!^G^@^Y^L^@^Z^@^[^G^@^\^L^@^]^@^^^L^@^]^@^_^A^@
HelloWorld^A^@^Pjava/lang/Object^A^@^Pjava/lang/System^A^@^Cout^A^@^ULjava/io/PrintStream;^A
^@^Sjava/io/PrintStream^A^@^Gprintln^A^@^U(Ljava/lang/String;)V^A^@^D(I)V^@!^@^F^@^G^@^@^@^@^@^B^@^A^@^H^@ ^@^A^@
3. Descompilando o arquivo HelloWorld.class e vendo o código fonte original
Para esta demonstração utilizaremos o decompilador Jad
que é gratuíto para um uso não comercial. Realize o download
da respectiva versão para o seu sistema operacional. Use o jad para realizar a engenharia reversa do arquivo HelloWorld.class e recuperer o código fonte original, como mostrado a seguir:
$ unzip jadls158.zip
$ ./jad HelloWorld.class
Parsing HelloWorld.class…
Generating HelloWorld.jad
$ vi HelloWorld.jad <Isto irá mostrar o código fonte original, fruto da execução da engenharia reversa>
Ofuscando a sua aplicação java
Agora iremos ver como ofuscar e proteger o seu código fonte da engenharia reversa, usando o ProGuard 
que é um software gratuíto com licensa GPL.
1. Faça o Download
e instale o ProGuard
$ cd /home/jsmith
$ unzip proguard4.2.zip
2. Crie um arquivo de configuração proguard
Crie um myconfig.pro que conterá as informações sobre a sua aplicação java.
-injar : Especifica a localização do seu arquivo jar, o qual contém os arquivos .class da compilação da sua classe java.
-outjar : Este é o arquivo jar que o proguard irá criar após a ofuscação do código. Este conterá todo o código alterado, lacrado, com as nomenclaturas de métodos e variáveis obscurar, o que vai dificultar muito para algum humano converseguir realizar a engenharia reversa.
-printmapping : ProGurad irá gerar uma saída com todas as saídas, em um arquivo com as informações mapeadas, em um arquivo que você especificar.
-keep : Incida os arquivos .class ou os métodos que você não quer que o ProGuard altere.
Para exemplificar, imagineos um mypkg.MainAppFrame como informação de onde está a nossa classe principal da aplicação, sendo esta classe neste exemplo, nós não queremos que seja ofuscada pelo ProGuard, como no exemplo a seguir:
$ cat myconfig.pro
-injars /home/jsmith/myapp.jar
-outjars /home/jsmith/myapp-obfuscated.jar This is the obfuscated jar file
-libraryjars /usr/java/jdk1.5.0_14/jre/lib/rt.jar
-printmapping proguard.map
-verbose
-keep public class mypkg.MainAppFrame
3. Execute o ProGuard
$ cd /home/jsmith/proguard4.2/lib
$ java -jar proguard.jar @myconfig.pro
Isto irá criar 2 arquivos, descritos a seguir:
* myapp-obfuscated.jar: Contém os arquivos das .class ofuscados da sua aplicação. E este você poderá distribuir sem medo algum de que alguem venha tentar realizar uma engenharia reversa, não que seja impossível, mas vai dar muito trabalho, o que acaba fazendo com que desistam da idéia.
* proguard.map: Este arquivo contém as informações do mapeamento para você se referenciar, sobre o que foi feito.
4. Exemplo de arquivo proguard.map
Este exemplo de arquivo proguard.map é o que indica o nome original que havia nos fontes java (nome do .class, métodos, variáveis, etc) e o respectivo nome a ser utilizado.
myapp.AppToolBar -> myapp.ae:
javax.swing.JButton btnNew -> d
javax.swing.JButton btnOpen -> e
5. Exemplo de código java (myapp.AppToolBar) antes de ser ofuscado
- btnNew = changeButtonLabel(btnNew, language.getText("new"));
- btnOpen = changeButtonLabel(btnOpen, language.getText("open"));
6. Exemplo de código fonte java que foi decompilado de um arquivo .class (myapp.ae) despois deste ter sido ofuscado
- d = a(d, n.a("new"));
- e = a(e, n.a("open"));
Aqui você pode ver a linha “btnNew = changeButtonLabel(btnNew, language.getText(”new”));” que foi traduzida para “d = a(d, n.a(”new”));”, pelo ProGuard, essa linha de código que não irá fazer sentido nenhum para alguem que venha a decompilar esta classe em uma engenharia reversa.