quarta-feira, 3 de setembro de 2008

Criptografia com Sha-1 ou Base64

Usando Sha-1 ou MD5, uma vez obtida a String criptografada não será possível reverter o processo (uso o termo criptografia embora este termo nao seja o mais correto para este caso). No caso de uma senha por exemplo, o que se faz é criptografar a entrada do usuário e comparar com a senha já criptografada no banco. De modo que nem mesmo pelo dado armazenado no banco se pode saber a senha do usuário, pois o que está armazenado no banco de dados é o resultado da criptografia da senha e não a senha.
Já com o Base64 é possível criptografar um dado e com a chave correta descriptografar o mesmo.
É comum utilizar algoritmos como o MD5 e o Sha-1 para a criptografia de senha, porque não convém deixar a própria senha armazenada em um banco. Já o Base64 é usado quando há a necessidade de se conhecer o dado criptografado, não apenas saber se é válido.
A seguir deixo duas classes, a primeira pode ser utilizada tanto com MD5 como com Sha-1, e a segunda classe utiliza o Base64.

Classe para MD5 e Sha-1:


import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
*
* Essa classe pode ser usada tanto com o algoritmo MD5 como
* com o Sha-1. Uma vez criptografado um dado, nao sera possivel
* conhecer o valor original. Para saber se este dado corresponde
* a algum outro, voce deve comparar a string resultante da
* criptografia de ambos.
*
*/
public class CriptografiaMD5 {

private static MessageDigest md = null;

static {
try {
// Pode-se usar o algoritmo Sha-1 tambem,
// basta bustituir na linha abaixo.
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
}

private static char[] hexCodes(byte[] text) {
char[] hexOutput = new char[text.length * 2];
String hexString;
for (int i = 0; i < text.length; i++) {
hexString = "00" + Integer.toHexString(text[i]);
hexString.toUpperCase().getChars(hexString.length() - 2,
hexString.length(), hexOutput, i * 2);
}
return hexOutput;
}

public static String criptografar(String pwd) {
if (md != null) {
return new String(hexCodes(md.digest(pwd.getBytes())));
}
return null;
}


public static void main(String[] args){
String senha = "123456";
System.out.println(CriptografiaMD5.criptografar(senha));

senha = "132546";
System.out.println(CriptografiaMD5.criptografar(senha));
}
}


Classe para Base64:

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.KeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

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

/**
*
* Essa classe usa Base64 e permite a descriptografia, usando-se a
* chave correta.
*
*/
public final class CriptografiaBase64 {
private static SecretKey skey;
private static KeySpec ks;
private static PBEParameterSpec ps;
private static final String algorithm = "PBEWithMD5AndDES";
private static BASE64Encoder enc = new BASE64Encoder();
private static BASE64Decoder dec = new BASE64Decoder();
static {
try {
SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);

ps = new PBEParameterSpec (new byte[]{3,1,4,1,5,9,2,6}, 20);

// Esta e a chave que voce quer manter secreta.
ks = new PBEKeySpec ("EAlGeEen3/m8/YkO".toCharArray());

skey = skf.generateSecret (ks);
} catch (java.security.NoSuchAlgorithmException ex) {
ex.printStackTrace();
} catch (java.security.spec.InvalidKeySpecException ex) {
ex.printStackTrace();
}
}

public static final String encrypt(final String text)
throws
BadPaddingException,
NoSuchPaddingException,
IllegalBlockSizeException,
InvalidKeyException,
NoSuchAlgorithmException,
InvalidAlgorithmParameterException {

final Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, skey, ps);
return enc.encode (cipher.doFinal(text.getBytes()));
}

public static final String decrypt(final String text)
throws
BadPaddingException,
NoSuchPaddingException,
IllegalBlockSizeException,
InvalidKeyException,
NoSuchAlgorithmException,
InvalidAlgorithmParameterException {

final Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, skey, ps);
String ret = null;
try {
ret = new String(cipher.doFinal(dec.decodeBuffer (text)));
} catch (Exception ex) {
}
return ret;
}

public static void main(String[] args) throws Exception {
String password = "123456";
String encoded = CriptografiaBase64.encrypt (password);
System.out.println ("\nString: " + password);
System.out.println ("String criptografada: " + encoded);
System.out.println ("String descriptografada: " +
CriptografiaBase64.decrypt(encoded));

password = "123459";
encoded = CriptografiaBase64.encrypt (password);
System.out.println ("\nString: " + password);
System.out.println ("String criptografada: " + encoded);
System.out.println ("String descriptografada: " +
CriptografiaBase64.decrypt(encoded));
}
}


Nenhum comentário: