Michael
Michael

Reputation: 73

Why PBE generates same key with different salt and iteration count?

I am trying to test PBE encryption/decryption. I found that PBE generates same key with different salt and iteration count. Of course, the password used is same. As what I understand, same password and different salt/iteration should get different keys. Below is my test code:

import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

public class PBETest
{
    public static void main(String[] args)
        throws Exception
    {
        String algo = "PBEWithSHA1andDESede";
        System.out.println("====== " + algo + " ======");

        char[] password = "password".toCharArray();
        SecureRandom rand = new SecureRandom();
        byte[] salt = new byte[32];
        rand.nextBytes(salt);
        int iterationCount = rand.nextInt(2048);

        //encryption key
        PBEKeySpec          encPBESpec = new PBEKeySpec(password, salt, iterationCount);
        SecretKeyFactory    encKeyFact = SecretKeyFactory.getInstance(algo);
        Key encKey = encKeyFact.generateSecret(encPBESpec);
        System.out.println("encryptioin iteration: " + iterationCount);

        //decryption key
        rand.nextBytes(salt);
        iterationCount = rand.nextInt(2048);
        PBEKeySpec          decPBESpec = new PBEKeySpec(password, salt, iterationCount);
        SecretKeyFactory    decKeyFact = SecretKeyFactory.getInstance(algo);
        Key decKey = decKeyFact.generateSecret(decPBESpec);
        System.out.println("decryptioin iteration: " + iterationCount);

        System.out.println("encryption key is same as decryption key? " + encKey.equals(decKey));

    }

}

I am expecting the final output is a false. Did I do anything wrong?

Upvotes: 7

Views: 14008

Answers (2)

tbroberg
tbroberg

Reputation: 635

You got spectacularly lucky, and your random salts and iteration counts just happened to match. Go directly to Las Vegas. Now. ;)

I googled for PBEWithSHA1andDESede and tracked down this example: http://cryptofreek.org/2010/06/04/encrypting-and-decrypting-files-with-java wherein he specifies the key alone with new PBEKeySpec(password) and creates a separate PBEParameterSpec using the salt and iteration count which is then passed to Cipher.init().

So, no, you did nothing wrong, you just stopped before the salt and count got stuffed into the cipher.

Upvotes: 6

bozu
bozu

Reputation: 43

If you use PBKDF2WithHmacSHA1 instead of PBEWithSHA1andDESede your assumption works as it supports salt. You just need to add a the keyLength parameter to PBEKeySpec:

        String algo = "PBKDF2WithHmacSHA1";

...

        PBEKeySpec decPBESpec = new PBEKeySpec( password, salt, iterationCount, 128 );

I have run a test and the result is: false.

However, note that for encryption and decryption to work properly you need to use the same salt and iteration count when generating the key.

Upvotes: 3

Related Questions