Criptografia utilizando SALT

Bom dia,

Eu estou pesquisando métodos de criptografia em java para utilizar em minha aplicação e encontrei um interessante no blog da caelum (http://blog.caelum.com.br/guardando-senhas-criptografadas-em-java/). A partir deste site eu montei meu código de criptografia de senha e tudo funcionou perfeitamente, porem eu queria implementar o tão falado SALT.
Eu pesquisei sobre, achei vários assuntos e já até entendi o q é e para q serve o SALT, inclusive lendo alguns outros tópicos aqui mesmo do fórum, mas não consigo encontrar uma forma de fazer isso na pratica, por isso venho aqui pedir a ajuda de vcs, para quem souber, me ensinar a implementar o salt no meu código, segue abaixo o código como esta agora (sem salt):

public void setSenha(String senha) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest algorithm = MessageDigest.getInstance(“SHA-256”);
byte messageDigest[] = algorithm.digest(senha.getBytes(“UTF-8”));
StringBuilder hexString = new StringBuilder();

            for (byte b : messageDigest) {
	  hexString.append(String.format("%02X", 0xFF & b));
	}
	this.senha = hexString.toString();

}

Vou dar um exemplo.

Digamos que você tenha um usuário e senha (usuário = “pacarana”, senha = “Dinomys branickii”. )

Como você deve saber, o SHA-256 dessa senha (convertida para bytes usando a codificação UTF-8 ) é em hexadecimal, 3db74573fef5cf4a8a3fe37822405dbf6802cffc9f68491c257f37fe28d080fa (até aí você sabe disso).

O que normalmente se deve fazer é criar um salt aleatório e guardar isso ns sua base. Então, devemos combinar esse salt com a senha para podermos ter um outro valor de SHA-256.

Digamos que o salt tenha 16 bytes e seja, em hexadecimal,

[color=red]2f 3e d7 3f 2c df b0 ff f5 bf ca 82 1b 80 60 02[/color]

O SHA-256 da concatenação Senha || salt é:

[color=green]e2b2386e9391e2e281ba00da26ca415cac5ac0c9959e086c993c44c64307c1ff[/color]
(Note que a concatenação Senha || Salt é:

0000    44 69 6E 6F 6D 79 73 20  62 72 61 6E 69 63 6B 69   Dinomys branicki
0010    69 2F 3E D7 3F 2C DF B0  FF F5 BF CA 82 1B 80 60   i/>.?,...§.....`
0020    02                                                 .

Portanto, como você faria isso?

  1. No campo senha, guardaria
    [color=red]2f3ed73f2cdfb0fff5bfca821b806002[/color][color=green]e2b2386e9391e2e281ba00da26ca415cac5ac0c9959e086c993c44c64307c1ff[/color]
  2. Na hora de validar essa senha, recuperaria esse valor ([color=red]2f3ed73f2cdfb0fff5bfca821b806002[/color][color=green]e2b2386e9391e2e281ba00da26ca415cac5ac0c9959e086c993c44c64307c1ff[/color]) e atribuiria os bytes [color=red]2f3ed73f2cdfb0fff5bfca821b806002[/color] ao salt
  3. Então, iria concatenar a senha que você for ler do usuário (digamos “Phoberomys pattersoni” com os bytes de salt.)
    A concatenação seria:
0000    50 68 6F 62 65 72 6F 6D  79 73 20 70 61 74 74 65   Phoberomys patte
0010    72 73 6F 6E 69 2F 3E D7  3F 2C DF B0 FF F5 BF CA   rsoni/>.?,...§..
0020    82 1B 80 60 02                                     ...`.

e ao calcular o SHA-256, você obteria
0352c93161c78f947afcca78b80facb1013952e3352cb1793ca14c69f9e7ba1a
que é obviamente diferente de
[color=green]e2b2386e9391e2e281ba00da26ca415cac5ac0c9959e086c993c44c64307c1ff[/color]
que é o valor correto do SHA256 (Senha || Salt) que você leu da base.

Veja que para isso funcionar direito é necessário ter um bom gerador de números aleatórios. Usar java.security.SecureRandom e chamar o método getBytes(), passando um array de 16 bytes, é uma excelente idéia.

Entendi, minha pergunta talvez seja besta mas eu realmente nao entendi uma coisa, se eu vou guardar o salt em uma coluna do banco e a senha em outra coluna, a partir do momento que alguem tem acesso a minha tabela, o salt nao faria diferença pq o hacker desconsideraria a coluna do salt e tentaria quebrar apenas a senha não é?? Ou no caso eu devo guardar o salt em outra tabela?? ainda não entendi muito bem essa parte de salvar tudo no BD.

Obs: se alguem tiver um exemplo de codigo de como gerar o salt eu agradeceria.