What is difference between SecretKey vs SecretKeySpec classes in Java?
The documentation of SecretKeySpec says:
it can be used to construct a SecretKey from a byte array
In this code, if I print secretKey.getEncoded() or secret.getEncoded(), in hex then both give the same output. So why do we need the 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");
Here is the output of both calls to getEncoded():
00367171843C185C043DDFB90AA97677F11D02B629DEAFC04F935419D832E697
Every
SecretKeyhas an associated algorithm name. You cannot use aSecretKeywith algorithm"DES"in a context where an AES key is needed, for example.In your code, the following line produces a
SecretKey:However, at this point the key is not an AES key. If you were to call
secretKey.getAlgorithm(), the result is"PBKDF2WithHmacSHA1". You need some way of telling Java that this is actually an AES key.The easiest way to do this is to construct a new
SecretKeySpecobject, using the original key data and explicitly specifying the algorithm name:Note: I would personally declare
secretas aSecretKey, since I don't think you'll need to care about the concrete implementation after this.