web-dev-qa-db-fra.com

Pourquoi une SecretKeySpec est-elle nécessaire pour dériver une clé d'un mot de passe en Java?

Quelle est la différence entre les classes SecretKey et SecretKeySpec en Java?

La documentation de SecretKeySpec dit:

il peut être utilisé pour construire une SecretKey à partir d'un tableau d'octets

Dans ce code, si j'imprime secretKey.getEncoded() ou secret.getEncoded(), en hexadécimal, les deux donnent la même sortie. Alors pourquoi avons-nous besoin du SecretKeySpec?

final String password = "test";
int pswdIterations = 65536  ;
int keySize = 256;
byte[] ivBytes;
byte[] saltBytes = {0,1,2,3,4,5,6};

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

PBEKeySpec spec = new PBEKeySpec(
                    password.toCharArray(), 
                    saltBytes, 
                    pswdIterations, 
                    keySize
                    );

SecretKey secretKey = factory.generateSecret(spec);

SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(),"AES");

Voici la sortie des deux appels à getEncoded():

00367171843C185C043DDFB90AA97677F11D02B629DEAFC04F935419D832E697

13
Riley Willow

Chaque SecretKey a un nom d'algorithme associé. Vous ne pouvez pas utiliser un SecretKey avec l'algorithme "DES" Dans un contexte où une clé AES est nécessaire, par exemple.

Dans votre code, la ligne suivante produit un SecretKey:

SecretKey secretKey = factory.generateSecret(spec);

Cependant, à ce stade, la clé est pas une clé AES. Si vous deviez appeler secretKey.getAlgorithm(), le résultat est "PBKDF2WithHmacSHA1". Vous avez besoin d'un moyen de dire à Java qu'il s'agit en fait d'une clé AES.

La façon la plus simple de le faire est de construire un nouvel objet SecretKeySpec, en utilisant les données de clé d'origine et en spécifiant explicitement le nom de l'algorithme:

SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(),"AES");

Remarque: Je déclarerais personnellement secret comme SecretKey, car je ne pense pas que vous devrez vous soucier de l'implémentation concrète après cela.

17
Duncan Jones

SecretKey n'est qu'une interface qui nécessite une implémentation spécifique au fournisseur. SecretKeySpec est une classe concrète qui permet une construction facile de SecretKey à partir du matériau de clé existant. Donc, pour obtenir SecretKey, vous devez utiliser la classe d'usine appropriée ou SecretKeySpec, comme raccourci.

8
Marko Živanović

SecretKey est une interface et SecretKeySpec est une implémentation de SecretKey

4
Buhake Sindi