2017-04-08 4 views
0

Nous Hashage un mot de passe en utilisant l'algorithme de PBKDF2, en utilisant la fonction SecretKeyFactory.generateSecret, comme ceci:SecretKeyFactory.generateSecret meurt avec InvalidKeySpecException sur IBM Java

final SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(algorithm); 
final PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, iterations, hashLength); 
final SecretKey secretKey = secretKeyFactory.generateSecret(keySpec); 
return secretKey.getEncoded(); 

Tout semble fonctionner très bien, cependant, sur le serveur de production, quand il est en cours d'exécution dans IBM Java, il meurt avec java.security.spec.InvalidKeySpecException: Impossible de générer la clé secrète:

Caused by: java.security.spec.InvalidKeySpecException: Could not generate secret key 
    at javax.crypto.SecretKeyFactory.generateSecret(Unknown Source) 
    at our.Implementation.doHash(Hasher.java:71) 
    ... 48 more 
Caused by: java.lang.RuntimeException: Error deriving PBKDF2 keys 
    at com.ibm.crypto.provider.PBKDF2KeyImpl.a(Unknown Source) 
    at com.ibm.crypto.provider.PBKDF2KeyImpl.<init>(Unknown Source) 
    at com.ibm.crypto.provider.PBKDF2HmacSHA1Factory.engineGenerateSecret(Unknown Source) 
    ... 50 more 

Nous avons essayé de changer le nombre d'itérations, la taille de hachage généré et t il taille de sel, mais rien n'a aidé. Qu'est-ce que je fais mal?

Répondre

0

Apparemment, il semble que l'implémentation IBM Java de PBKDF2 insiste sur le fait que le mot de passe ne doit pas être vide. Lorsque c'est le cas, l'implémentation génère une exception.

Les mots de passe vides sont sans doute un cas de bordure, cependant, le premier cas de test était exactement cela, donc il semblait que le code ne fonctionnait pas du tout. En outre, dans un cas de bordure, vous devez vous assurer que cela ne se produit jamais (les validations demandant à l'utilisateur de ne pas avoir de mot de passe vide), ou vous devez le gérer avec élégance.

Si vous avez vraiment besoin de prendre en charge des mots de passe vides, vous devez les gérer comme un cas particulier, ou simplement normaliser tous les mots de passe afin que l'entrée de PBKDF2 ne soit jamais vide. Cependant, vous devez vous assurer que vous ne compromettrez pas la sécurité de cette façon. En fin de compte, nous avons choisi de préfixer tous les mots de passe avec leur longueur, de sorte que même les mots de passe vides se terminent par une chaîne non vide. Comme ça:

final String prefixedPassword = String.format(Locale.ROOT, "%08x%s", password.length(), password);