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
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.
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.
SecretKey
est une interface et SecretKeySpec
est une implémentation de SecretKey