JDK-8194631 : Reinitialization fails from invalid salt to valid salt using javax.crypto.Cipher.init
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.crypto
  • Affected Version: 8u151
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86_64
  • Submitted: 2017-12-22
  • Updated: 2018-01-04
  • Resolved: 2018-01-04
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
1.8.0_102
1.8.0_144
1.8.0_151
9.0.1

ADDITIONAL OS VERSION INFORMATION :
Darwin Kernel Version 17.3.0
2.6.32-696.16.1.el6.x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
This can be marked as a duplicate of JDK-4953555 and included in that chain of reports.  The attached source is a slightly modified version of what is in that bug report.

The code included shows that, in addition to the incorrect behavior occurring when an invalid key is present, it also occurs if invalid parameters (in this case the salt) is passed to init.

Tested on multiple OS's and java versions as noted.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Initialize with invalid salt
Initialize with good salt
java.security.InvalidKeyException: No installed provider supports this key: com.sun.crypto.provider.PBEKey
	at javax.crypto.Cipher.chooseProvider(Cipher.java:893)
	at javax.crypto.Cipher.init(Cipher.java:1396)
	at javax.crypto.Cipher.init(Cipher.java:1327)
	at e5.main(e5.java:57)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.security.InvalidAlgorithmParameterException;
import java.security.Key;
import java.security.AlgorithmParameters;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

public class e5 {

  public static void main(String argv[]) {
    Key k;
    Cipher c;
    AlgorithmParameters params = null;

    String alg = "PBEWITHMD5ANDDES";
    byte[] salt = {
        (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
        (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
    };
    byte[] invalidSalt = {
        (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c
    };
    int count = 20;

    PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 20);
    PBEParameterSpec invalidParamSpec = new PBEParameterSpec(invalidSalt, 20);


    String s = "My wonderfull password that is long enough. Tra-la-la, let me sing a song";

    try {
      int kl = Cipher.getMaxAllowedKeyLength(alg) / 8;
      String p = (kl >= s.length()) ? s: s.substring(0, kl);
      KeySpec ks = new PBEKeySpec(p.toCharArray(), salt, count, kl * 8);

      SecretKeyFactory skf =
          SecretKeyFactory.getInstance(alg);

      // PBE algorithm is symmetric.
      k = skf.generateSecret(ks);

      c = Cipher.getInstance(alg);

      try {
        System.out.println("Initialize with invalid salt");
        c.init(Cipher.ENCRYPT_MODE, k, invalidParamSpec);
      } catch (InvalidAlgorithmParameterException e) {
      }

      System.out.println("Initialize with good salt");
      c.init(Cipher.ENCRYPT_MODE, k, paramSpec);

      System.out.println("passed");

    } catch (Exception e) {
      e.printStackTrace(System.out);
    }
  }
}
---------- END SOURCE ----------