PBKDF2 interoparabilidade java e javascript (node-forge)

O PBKDF2 é uma função de derivação de chave com base em senha. As funções de derivação são utilizadas para reduzir as vulnerabilidades de ataques de força bruta.

No frontend eu utilizo o forge-js e no backend utilizo o java. Para trabalhar com PBKDF2 em ambos é necessário alinhar a função para que ambos utilizem os mesmos parametros.

A função PBKDF2 pode ser descrita como:

1
DK = PBKDF2(PRF, Password, Salt, c, dkLen)

Onde DK é a chave gerada, o Salt é uma sequência de bits no caso eu uso os bytes de uma string, o password é uma string , c é o número de iterações desejadas e PRF é uma função pseudo-randômica. O segredo é definir no java a mesma PRF do forge-js que por padrão usa o HMAC-SHA1.

Abaixo segue a configuração que utilizo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static byte[] hashPassword( final char[] password, final byte[] salt, final int iterations, final int keyLength ) {

try {
SecretKeyFactory skf = SecretKeyFactory.getInstance( "PBKDF2WithHmacSHA1" );
PBEKeySpec spec = new PBEKeySpec( password, salt, iterations, keyLength );
SecretKey key = skf.generateSecret( spec );
byte[] res = key.getEncoded( );
return res;

} catch(NoSuchAlgorithmException | InvalidKeySpecException e ) {
throw new RuntimeException( e );
}
}
public static void main(String[] args) {
Base64.Encoder encoder = Base64.getEncoder();

byte[] pass = hashPassword("teste".toCharArray(), "123".getBytes(), 4096, 128);

System.out.println(encoder.encodeToString(pass));

}

Em java tem que usar uma instância PBKDF2WithHmacSHA1 .

Em java o keyLength é em bits no javascript é me bytes.

1
2
let derivedKey = forge.pkcs5.pbkdf2("teste", "123", 4096, 16)
console.log(forge.util.encode64(derivedKey))

Para saber mais

Exploiting some weaknesses of PBKDF2