Usando criptografia em JAVA

Usar criptografia em Java não é uma tarefa difícil. Com algumas pesquisas no Google, encontramos diversos resultados que podem nos atender. Recentemente, tive que usar em um projeto um esquema de criptografia onde informações seriam criptografas e descriptografadas a quase todo momento.

Assim, resolvemos criar um classe de criptografia e um exceção que representasse qualquer erro ocorrido na criptografia e descriptografia. A forma de criptografia que escolhemos, foi a AES. Esse tipo de criptografia é uma das mais seguras já desenvolvidas. Se quiser mais informações sobre esse a AES, de uma olhada aqui.

Para uma criptografia AES você precisará de uma chave. Essa chave será usada por quem quer criptografar e quem quer descriptografar. Portanto, ela deverá ficar com quem somente tem autorização para fazer tais tarefas de criptografia ou descriptografia.

Em Java, essa chave é representada por um array de bytes, como abaixo:

public static final byte[] CHAVE = {85, 10, 0, -25, 68, 88, 46, 37, 107, 48, 10, -1, -37, -90, 70, -36};

Em nossa classe de criptografia, haverá um método para criptografar informações onde esse método receberá como parâmetros a informação a ser criptografada, que será uma String e também receberá a chave de criptografia, que eu mostrei acima.

Haverá em nossa classe também o método de descriptografia onde ele irá receber também dois parâmetros. A chave de criptografia (acima) e a informação criptografada, que é uma String.

Sendo assim, nossa classe de criptografia ficará da seguinte forma:

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class Encrypter {

	private static final String METODO_ENCRIPTACAO = "AES";
	public static final byte[] CHAVE = {85, 10, 0, -25, 68, 88, 46, 37, 107, 48, 10, -1, -37, -90, 70, -36};;

	public static String encriptar(byte[] key, String value)
			throws EncryptorException {

		try {
			SecretKeySpec skeySpec = new SecretKeySpec(key, METODO_ENCRIPTACAO);

			Cipher cipher = Cipher.getInstance(METODO_ENCRIPTACAO);
			cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
			byte[] encrypted = cipher.doFinal(value.getBytes());

			return new BASE64Encoder().encode(encrypted);
		}
		catch (Exception e) {
			throw new EncryptorException("Erro ao criptografar informações " + e.getMessage());
		}
	}

	public static String decriptar(byte[] key, String encrypted)
			throws EncryptorException {

		byte[] decrypted = null;

		try {
			SecretKeySpec skeySpec = new SecretKeySpec(key, METODO_ENCRIPTACAO);

			byte[] decoded = new BASE64Decoder().decodeBuffer(encrypted);

			Cipher cipher = Cipher.getInstance(METODO_ENCRIPTACAO);
			cipher.init(Cipher.DECRYPT_MODE, skeySpec);
			decrypted = cipher.doFinal(decoded);
		}
		catch (Exception e) {
			throw new EncryptorException("Erro ao descriptografar informações " + e.getMessage());
		}

		return new String(decrypted);
	}
}

Você deve estar se perguntando, mas o que acontece se eu chamar o método de descriptografia e enviar uma informação não criptografada? A resposta é simples: vai dar erro e será lançada uma exceção.

Repare no código que as Exception são capturadas e já é lançada a EcryptorException. Essa exceção é criada somente para representar erros que possam ocorrer nessa classe de criptografia.

A classe de Exceção é assim:

public class EncryptorException extends Exception {

	private static final long serialVersionUID = -1295447857016462572L;

	public EncryptorException(String mensagem) {
		super(mensagem);
	}
}

Nenhum segredo também.

Agora basta testar a sua classe chamando os métodos de criptografia e descriptografia. Vamos fazer o teste.

Segue meu exemplo onde eu criptografo uma String e a String criptografada retornada é usada como parâmetro na chamada da descriptografia. Veja só o exemplo:

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		String informacao = "Lynyrd Skynyrd";
		String informacaoCriptografada = null;
		String informacaoDescriptografada = null;

		try {
			informacaoCriptografada = Encrypter.encriptar(Encrypter.CHAVE, informacao);
			System.out.println("Informação criptografada: " + informacaoCriptografada);

			informacaoDescriptografada = Encrypter.decriptar(Encrypter.CHAVE, informacaoCriptografada);
			System.out.println("Informação descriptografada: " + informacaoDescriptografada);
		} catch (EncryptorException e) {
			e.printStackTrace();
		}
}

Se você usou o exemplo da minha classe de criptografia sem mudar a chave e executou o teste acima também sem mudar a informação a ser criptografada, você terá uma saída para console que será a seguinte:

Informação criptografada: Ng7uAaxZKEReAxrdwn2GEw==

Informação descriptografada: Lynyrd Skynyrd

Se você conseguiu chegar no resultado acima, quer dizer que tudo deu certo! Ainda existe mais alguns detalhes sobre a chave de criptografia onde explico um pouco mais abaixo.

SOBRE A CHAVE DE CRIPTOGRAFIA

A chave de criptografia é única, portanto você não irá querer usar a chave que coloquei no meu exemplo. Você irá querer ter sua própria chave de criptografia. Para fazer isso, criei um método onde ele devolve as chaves de criptografia prontas em array de bytes.

O método não é difícil de entender. Já existe um gerador de chaves nativos do Java chamado KeyGenerator. Ao chama-lo, ele devolve um array de bytes. O método que criei apenas obtém esse array de bytes e percorre o array exibindo cada byte para console.

No final, você terá seus bytes em console para usar em código. basta copiar e colar.

Segue o método que gera a chave:

public static void gerarChave() {
		try {
			KeyGenerator keyGen = KeyGenerator.getInstance(METODO_ENCRIPTACAO);

			System.out.println("Chave AES:");
			byte[] chave = keyGen.generateKey().getEncoded();

			System.out.print("{");
			for (byte b : chave) {
				System.out.print("" + b + ", ");
			}
			System.out.println("}");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

Certo pessoal?

Então é isso! Até a próxima.

  • arnaldo

    valeu estava procurando isso!! funcionou blz!!

  • vh

    Bom post. Apenas corrija o erro de ortografia “excessão” por “exceção”.

  • http://www.ricardogiaviti.com.br Ricardo Giaviti

    Corrigido vh.

    Obrigado pelo comentário.

  • Julio

    Muito bom o post. Também criei um post em meu blog ensinando criptografar e descriptografar utilizando uma bibliotéca chamada
    Jasypt. Muito simples de utilizar.
    http://www.javabr.com/blog/java-2/criptografia-e-descriptografia-em-java/

  • Marcospaulo_mpl

    Ola ja que vc consegui rodar este programa criptografia em JAVA do post acima queria saber se vc tem ele ainda e se poderia me passar pois eu sou novato a respeito de java
    e quais bibibliotecas necessarios para rodar este programa do post acima.
    Grato.

  • Joaodasilva

    Muito bom artigo!

  • http://blog.hallanmedeiros.com HAllan

    Parabens pelo post! Muito bem explicado!