18

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

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
Riley Willow
  • 594
  • 2
  • 5
  • 21

3 Answers3

23

Every SecretKey has an associated algorithm name. You cannot use a SecretKey with algorithm "DES" in a context where an AES key is needed, for example.

In your code, the following line produces a SecretKey:

SecretKey secretKey = factory.generateSecret(spec);

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 SecretKeySpec object, using the original key data and explicitly specifying the algorithm name:

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

Note: I would personally declare secret as a SecretKey, since I don't think you'll need to care about the concrete implementation after this.

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
  • 1
    "Every SecretKey has an associated algorithm name." , wouldn't that make the encryption less secure ? shouldn't key should be independent of the algorithm ? , for instance, If someone got the key, wouldn't they be able to identify the algorithm used for encryption ? – Riley Willow Nov 21 '14 at 13:13
  • 13
    Strong cryptography works on the basis that everyone knows everything, *except* the value of your key. Once someone has your key, figuring out how you encrypted data is a trivial task. So no, your algorithm need not be secret. – Duncan Jones Nov 21 '14 at 14:15
11

SecretKey is just an interface that requires provider-specific implementation. SecretKeySpec is a concrete class that allows for easy construction of SecretKey from existing key material. So, in order to get SecretKey, you need to use either appropriate factory class or SecretKeySpec, as a shortcut.

6

SecretKey is an interface and SecretKeySpec is an implementation of SecretKey

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228