Generating key from password without salt

1.4k Views Asked by At

Java has a convinient class PBEKeySpec that lets you generate a secret key from a password using values of iteration count, key length and salt for decryption purposes. See the example below.

private static Key getPasswordBasedKey(String cipher, int keySize, char[] password) throws NoSuchAlgorithmException, InvalidKeySpecException {
    byte[] salt = new byte[100];
    SecureRandom random = new SecureRandom();
    random.nextBytes(salt);
    PBEKeySpec pbeKeySpec = new PBEKeySpec(password, salt, 1000, keySize);
    SecretKey pbeKey = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256").generateSecret(pbeKeySpec);
    return new SecretKeySpec(pbeKey.getEncoded(), cipher);
}

But what if salt is not a part of specific case of encryption? Then in order to get correct output I'll have to decrypt without salt as well. But in this case constructor of PBEKeySpec(char[] password, byte[] salt, int iterationCount, int keyLength) will throw an exception (NullPointerException if salt is null, IllegalArgumentException if it's an empty array). So my question is: is there any way available in Java to generate secret key from a password taking account of iterationCount and keyLength but skipping salt?

Why I need it:

  • Data was encrypted this way (no salt) on the other end. I can't change it.
  • So now i need a tool in Java that will let me decrypt it with no requirement to have a salt (but still with use of iteration count and key length).
  • I can't find such tool.
1

There are 1 best solutions below

1
Progman On

To get the same secret key using the PBEKeySpec class, you need the same password, salt and iteration count (and key size). You cannot skip the salt part and expect to get the same password based secret key since there are 2^(salt-length) possible ways on how the key can be generated with only these provided data.

The salt doesn't need to be private for the password based key generation. See the quote from the answer Java 256-bit AES Password-Based Encryption:

Share the password (a char[]) and salt (a byte[]—8 bytes selected by a SecureRandom makes a good salt—which doesn't need to be kept secret) with the recipient out-of-band.

The answer also explain that the iteration and key size is fixed or known.

Also check the RFC2898 PKCS #5: Password-Based Cryptography Specification Version 2.0 - Page 5:

Salt and iteration count formed the basis for password-based
encryption in PKCS #5 v1.5, and adopted here as well for the various
cryptographic operations. Thus, password-based key derivation as
defined here is a function of a password, a salt, and an iteration
count, where the latter two quantities need not be kept secret.

with emphasis on "[...], where the latter two quantities need not be kept secret" (namely the salt and iteration).

To answer your question:

Is there any way to generate (the same)¹ secret key from a password taking account of iterationCount and keyLength but skipping salt?

¹ (added by me)

The answer is: No.