Java fornece uma api Java Cryptography Architecture para trabalhar com criptografia de dados e através dessa api conseguimos criptografar dados em vários tipos de algoritmos como MD5 e SHA. Com isso, vou aplicar os recursos dessa api em uma aplicação Java.
Neste exemplo irei demonstrar como utilizar os algoritmos MD5, SHA-256 e SHA-512 e caso queira saber mais, nos endereços a seguir você poderá entender melhor como esses algoritmos funcionam.
Referência para algoritmo SHA. Referência para algoritmo MD5.
O exemplo que irei criar está representado no driagrama UML a seguir:
Agora vamos ao código, irei começar criando a interface Cryptography.java
1
2
3
4
5
6
7
import java.security.NoSuchAlgorithmException;
public interface Cryptography {
String encrypt(String value) throws NoSuchAlgorithmException;
}
Agora vou criar uma classe abstrata que conterá o básico para efetuar uma criptografia, contudo esta classe não será responsável por determinal qual tipo de algoritmo será utilizado.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Encoder;
public abstract class CryptographyGeneric {
private MessageDigest messageDigest;
private BASE64Encoder encoder;
protected void useAlgorithm(String algorithm) throws NoSuchAlgorithmException {
if (messageDigest == null || messageDigest.getAlgorithm() != algorithm) {
messageDigest = MessageDigest.getInstance(algorithm);
}
if (encoder == null) {
encoder = new BASE64Encoder();
}
}
protected String encryptByAlgorithm(String algorithm, String value) throws NoSuchAlgorithmException {
if (value == null) {
throw new IllegalArgumentException("The value is null.");
}
useAlgorithm(algorithm);
byte[] hash = messageDigest.digest(value.getBytes());
return encoder.encode(hash);
}
}
Agora irei criar as classes que especificam qual tipo de algoritmo irá ser utilizado. Primeiro vou criar a classe para o algoritmo MD5.
1
2
3
4
5
6
7
8
9
import java.security.NoSuchAlgorithmException;
public class CryptographyMD5 extends CryptographyGeneric implements Cryptography {
public String encrypt(String value) throws NoSuchAlgorithmException {
return encryptByAlgorithm("MD5", value);
}
}
Para o algoritmo SHA-256.
1
2
3
4
5
6
7
8
9
import java.security.NoSuchAlgorithmException;
public class CryptographySHA256 extends CryptographyGeneric implements Cryptography {
public String encrypt(String value) throws NoSuchAlgorithmException {
return encryptByAlgorithm("SHA-256", value);
}
}
E finalmente para o algoritmo SHA-512.
1
2
3
4
5
6
7
8
9
import java.security.NoSuchAlgorithmException;
public class CryptographySHA512 extends CryptographyGeneric implements Cryptography {
public String encrypt(String value) throws NoSuchAlgorithmException {
return encryptByAlgorithm("SHA-512", value);
}
}
Pronto, já temos nossas classes. Com isso podemos utilizar varios tipos de algoritmos em um mesmo objeto do tipo Cryptography.
Vamos realizar alguns testes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void main(String[] args) throws NoSuchAlgorithmException {
Cryptography cryptography;
//Criptografia usando MD5
cryptography = new CryptographyMD5();
System.out.println("MD5: " + cryptography.encrypt("Java Cryptography Architecture"));
//Criptografia usando SHA-256
cryptography = new CryptographySHA256();
System.out.println("SHA-256: " + cryptography.encrypt("Java Cryptography Architecture"));
//Criptografia usando SHA-512
cryptography = new CryptographySHA512();
System.out.println("SHA-512: " + cryptography.encrypt("Java Cryptography Architecture"));
}
O resultado desse teste será:
1
2
3
4
MD5: cJL5LHVk/rjt0HYpNoi/1g==
SHA-256: OtvmRxbTc7fp3SnfSKTgXVi81Gvp7+QPl1B4aCvLU48=
SHA-512: YSsyP2VOGxlwcX873AxlVGqTX4DsJE6XOBTQkjjX4M2zhrMChnohHIejLe1W7RRrfvfMMODiMBou
LqOXHXknig==
Após quase 1 mês esperando, finalmente minha compra feita na amazon.com chegou. Resolvi comprar uma pequena pilha composta por três livros para economizar no frete que as vezes pode até ficar mais caro que o próprio livro como ocorreu em uma outra compra que fiz onde paguei U$9,90 no livro e aproximadamente U$14,00 no frete.
Neste atual pedido comprei os seguintes livros:
Escolhi esses livros por ver muitas recomendações e também por ser sobre um tema que me interessa muito, arquitetura e desenvolvimento de software, onde pretendo me especializar.
Já dei uma pequena folheada nos três livros e mesmo ainda não lido todos, pude ver que realmente possuem um conteúdo muito bom. Agora é só arrumar tempo entre o trabalho e a faculdade para conseguir lê-los. ;)
Algumas fotos que tirei dos livros:
Costumei ver algumas vezes trechos de códigos em Java onde seus desenvolvedores utilizaram o método toString() como um método conversor para String, quando na verdade a finalidade desse método é somente permitir que se obtenha algum representação significativa de um determinado objeto. A classe Object, que é a classe primordial possui este método e como todas as outras classes são herdadas da classe Object, todas elas têm um método toString().
Irei mostrar dois exemplos dos que mais costumo ver e também mostrar alguns cuidados que deve-se tomar:
Pegar um parâmetro da requisição:
1
String value = request.getParameter("parametro").toString();
De cara já é um código estranho, pois não existe a necessidade de converter o valor do parâmetro para String já que o método getParameter() já retorna uma String. Outro problema é que caso o parametro não exista você vai receber um belo NullPointerException. O correto seria:
1
String value = request.getParameter("parametro");
Pegar atributo da requisição:
1
String value = request.getAttribute("parametro").toString();
Parecido com o primeiro exemplo, caso o atributo não existe será lançado um NullPointerException. Como este método retorna um Object realmente devemos converter o valor do atributo para o tipo esperado, mas uma melhor forma de fazer essa conversão seria:
1
String value = (String) request.getAttribute("parametro");
Com isso deixo um pequena dica de como evitar bugs…
No dia 05/09 fui ao Itaucultural com o pessoal da facul para vermos o evento Emoção Art.ficial – Emergência (4ª Bienal de Arte e Tecnologia). Uma breve apresentação sobre o evento segundo o seu próprio site é:
No cotidiano, associamos a palavra emergência a hospitais e ambulâncias. Mas ela traz também outros significados menos óbvios, como realidades complexas surgindo da aplicação de regras simples. O cérebro, o formigueiro, as cidades e os softwares livres são exemplos de emergência sob este ponto de vista não convencional.
No evento pude ver diversos trabalhos, misturando tecnologia, arte e muita criatividade. Uma experiência interessante com a tecnologia e muito diferente, afinal as pessoas que trabalham com TI em geral, estão acostumadas a ver, ouvir e falar muito sobre tecnologia aplicada aos negócios (business).
Algumas dos trabalhos que mais gostei foram:
Performative Ecologies, de Ruairi Glynn (Irlandês, 2007) Trabalho baseado em robótica, contém quatro robôs que utilizam um software de reconhecimento de padrão facial e que consegue reconhecer a pessoa depois de ter sua foto armazenada.
The Mutations of the White Doe, de Nicolas Reeves (Canadá, 1990 - presente) Trabalho muito interessante onde a partir de uma música folclórica escandinava The White Doe, um algoritmo conseguiu transformá-la em três esculturas de polímero translúcido.
PixFlow #2, de LAb[au] (Bélgica, 2007) Trabalho composto de quatro displays dispostos verticalmente. Um software que simula um campo vetorial em que partículas fluem conforme a evolução de sua densidade tomando caminhos imprevisíveis e formando ramificações bem legais.
Fica aí a dica para um programa diferente. ;)
A IBTA criou uma promoção gratuíta para promover seus cursos, basta se cadastrar e concorrer. A promoção terminará no dia 15/10/2008 e irá premiar 5 pessoas com um IPhone 2G cada.