[quote=ViniGodoy]O tamanho da chave no AES é fixo. Você é obrigado a usar chaves com 128, 192 ou 256 bits. Cada caractere ocupa 8 bits, portanto, as senhas são limitadas a 16, 32 ou 64 caracteres.
Uma estratégia comum é usar um algoritmo de Hash, como o DES ou SHA-1, na senha digitada pelo usuário para gerar a seqüência que será usada como entrada para o AES.
No caso do SALT. Existe um ataque chamado “Rainbow Tables” que permite reverter um texto “hasheado” rapidamente. Ele consiste na elaboração de um cache. Por exemplo, você poderia criar um mapa com palavras comuns e seus hashes correspondentes e procurar por esses hashes num BD (o ataque é um pouco mais complexo que isso, mas a idéia básica é por aí).
A técnica de SALT consiste simplesmente em usar uma informação conhecida (como o id do usuário, ou um valor aleatório que será guardado junto da senha) junto ao Hash para evitar o esse ataque. Assim, por exemplo, se os usuários Vinicius, de id=1 e Paulo, de id=50 tiverem a senha “senhaguj”, você processaria o hash de “senha1” para o Vinicius e “senha50” para o Paulo, gerando hashes diferentes.
O fato dessa informação extra estar concatenada forçaria o atacante a ter uma tabela de hash extremamente gigante, o que torna o ataque inviável.[/quote]
Valeu Vini, eu li os dois sites que me recomendou e eu entendi bastante. Salt parece ser mais usado para banco de dados, onde se pode ter todos os hashes de senhas através de um ataque ao BD.
Como eu não terei nenhum armazenamento de senhas não precisarei do Salt.
Então resolvi usar um algorítimo de hash para minha senha e escolhi o SHA-256. O quê me dá 32 bits.
Entretanto ainda continuo com erro. Veja:
A classe criptográfica.
package editor;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
*
* @author Paulo Lopes
*/
public class Cifrador
{
private String textoNormal; //Texto a ser criptografado.
private String textoCifrado;
private final String ALGORITIMO = "AES";
private Hasher hash;
public void criptografa(String senha, String texto) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, EncryptorException, UnsupportedEncodingException
{
hash = new Hasher();
byte[] chave = hash.getHash(senha);
try
{
SecretKeySpec skeySpec = new SecretKeySpec(chave, ALGORITIMO);
Cipher cipher = Cipher.getInstance(ALGORITIMO);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(texto.getBytes());
this.textoCifrado = new BASE64Encoder().encode(encrypted);
}
catch(NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e)
{
throw new EncryptorException("Erro ao criptografar informações.\n" + e.getMessage());
}
}
public String getTextoCifrado()
{
return textoCifrado;
}
public void decriptografa(String senha, String texto) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, EncryptorException
{
byte[] textoDecifrado = null;
hash = new Hasher();
try
{
byte[] chave = hash.getHash(senha);
SecretKeySpec skeySpec = new SecretKeySpec(chave, ALGORITIMO);
byte[] decoded = new BASE64Decoder().decodeBuffer(texto);
Cipher cipher = Cipher.getInstance(ALGORITIMO);
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
textoDecifrado = cipher.doFinal(decoded);
}
catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e)
{
throw new EncryptorException("Erro ao descriptografar informações.\n" + e.getMessage());
}
this.textoNormal = new String(textoDecifrado);
}
public String getTextoDecifrado()
{
return textoNormal;
}
}
A classe de Hash.
/*
* This class is responsible for provide a hash of password.
* This will return a hash of 256 bits necessary to AES key.
* Evertime that user going to cipher or decipher this class is called.
*/
package editor;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
*
* @author Paulo Lopes
*/
public class Hasher
{
private final String ALGORITIMO = "SHA-256";
public byte[] getHash(String senha) throws NoSuchAlgorithmException, UnsupportedEncodingException
{
MessageDigest messageDigest = MessageDigest.getInstance(ALGORITIMO);
messageDigest.update(senha.getBytes());
byte[] senhaByte = messageDigest.digest();
return senhaByte;
}
}
E recebo o erro:
editor.EncryptorException: Erro ao criptografar informações. Illegal key size or default parameters
Fazendo um chave.length()
simples, eu obtenho 32 bits normalmente da senha.
Onde pode estar ocorrendo o erro eu não tenho ideia.
Obrigado novamente!
Abraços.