Search code examples
javakeystorejavax.crypto

Generate a SecretKey from a password and get a password in cleartext from that Key


I do the following to store a SecretKey based on a user password in the KeyStore:

// load KeyStore

static byte[] salt = // for learning purposes
                     { (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c,
                       (byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99 };

String alias = "aeskey";
char[] password = "password".toCharArray();
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES/CBC/PKCS5Padding");
Entry aesentry = new KeyStore.SecretKeyEntry(secret);
store.setEntry(alias, aesentry, protParam);

Now I can get the SecretKey from the KeyStore:

KeyStore.SecretKeyEntry e = (SecretKeyEntry) store.getEntry("aeskey", protParam);
secret = e.getSecretKey();

How to get the inital password from that SecretKey?


Solution

  • You can't get the original password from the KeySpec. Some bytes of the password and the salt are chosen, to come up with the KeySpec. If you are trying to encrypt and decrypt text, you need to do the following:

    1. Generate the KeySpec using a password and salt
    2. Generate a SecretKey
    3. generate a Cipher instance using this
    4. Encrypt your text using this cipher

    Now, say you share your password and salt with someone offline. They can then use these to decrypt the encrypted text.

    See this for a good discussion on this.