src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java
changeset 51504 c9a3e3cac9c7
parent 48560 46e99460e8c9
child 54182 2e586b74722e
equal deleted inserted replaced
51503:0265a70ea2a5 51504:c9a3e3cac9c7
    91         } else {
    91         } else {
    92             this.passwd = passwd.clone();
    92             this.passwd = passwd.clone();
    93         }
    93         }
    94         // Convert the password from char[] to byte[]
    94         // Convert the password from char[] to byte[]
    95         byte[] passwdBytes = getPasswordBytes(this.passwd);
    95         byte[] passwdBytes = getPasswordBytes(this.passwd);
    96 
    96         // remove local copy
    97         this.salt = keySpec.getSalt();
    97         if (passwd != null) Arrays.fill(passwd, '\0');
    98         if (salt == null) {
    98 
    99             throw new InvalidKeySpecException("Salt not found");
       
   100         }
       
   101         this.iterCount = keySpec.getIterationCount();
       
   102         if (iterCount == 0) {
       
   103             throw new InvalidKeySpecException("Iteration count not found");
       
   104         } else if (iterCount < 0) {
       
   105             throw new InvalidKeySpecException("Iteration count is negative");
       
   106         }
       
   107         int keyLength = keySpec.getKeyLength();
       
   108         if (keyLength == 0) {
       
   109             throw new InvalidKeySpecException("Key length not found");
       
   110         } else if (keyLength < 0) {
       
   111             throw new InvalidKeySpecException("Key length is negative");
       
   112         }
       
   113         try {
    99         try {
       
   100             this.salt = keySpec.getSalt();
       
   101             if (salt == null) {
       
   102                 throw new InvalidKeySpecException("Salt not found");
       
   103             }
       
   104             this.iterCount = keySpec.getIterationCount();
       
   105             if (iterCount == 0) {
       
   106                 throw new InvalidKeySpecException("Iteration count not found");
       
   107             } else if (iterCount < 0) {
       
   108                 throw new InvalidKeySpecException("Iteration count is negative");
       
   109             }
       
   110             int keyLength = keySpec.getKeyLength();
       
   111             if (keyLength == 0) {
       
   112                 throw new InvalidKeySpecException("Key length not found");
       
   113             } else if (keyLength < 0) {
       
   114                 throw new InvalidKeySpecException("Key length is negative");
       
   115             }
   114             this.prf = Mac.getInstance(prfAlgo);
   116             this.prf = Mac.getInstance(prfAlgo);
   115             // SunPKCS11 requires a non-empty PBE password
   117             // SunPKCS11 requires a non-empty PBE password
   116             if (passwdBytes.length == 0 &&
   118             if (passwdBytes.length == 0 &&
   117                 this.prf.getProvider().getName().startsWith("SunPKCS11")) {
   119                     this.prf.getProvider().getName().startsWith("SunPKCS11")) {
   118                 this.prf = Mac.getInstance(prfAlgo, SunJCE.getInstance());
   120                 this.prf = Mac.getInstance(prfAlgo, SunJCE.getInstance());
   119             }
   121             }
       
   122             this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength);
   120         } catch (NoSuchAlgorithmException nsae) {
   123         } catch (NoSuchAlgorithmException nsae) {
   121             // not gonna happen; re-throw just in case
   124             // not gonna happen; re-throw just in case
   122             InvalidKeySpecException ike = new InvalidKeySpecException();
   125             InvalidKeySpecException ike = new InvalidKeySpecException();
   123             ike.initCause(nsae);
   126             ike.initCause(nsae);
   124             throw ike;
   127             throw ike;
   125         }
   128         } finally {
   126         this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength);
   129             Arrays.fill(passwdBytes, (byte) 0x00);
   127 
   130 
   128         // Use the cleaner to zero the key when no longer referenced
   131             // Use the cleaner to zero the key when no longer referenced
   129         final byte[] k = this.key;
   132             final byte[] k = this.key;
   130         final char[] p = this.passwd;
   133             final char[] p = this.passwd;
   131         CleanerFactory.cleaner().register(this,
   134             CleanerFactory.cleaner().register(this,
   132                 () -> {
   135                     () -> {
   133                     java.util.Arrays.fill(k, (byte)0x00);
   136                         Arrays.fill(k, (byte) 0x00);
   134                     java.util.Arrays.fill(p, '0');
   137                         Arrays.fill(p, '\0');
   135                 });
   138                     });
       
   139         }
   136     }
   140     }
   137 
   141 
   138     private static byte[] deriveKey(final Mac prf, final byte[] password,
   142     private static byte[] deriveKey(final Mac prf, final byte[] password,
   139             byte[] salt, int iterCount, int keyLengthInBit) {
   143             byte[] salt, int iterCount, int keyLengthInBit) {
   140         int keyLength = keyLengthInBit/8;
   144         int keyLength = keyLengthInBit/8;
   264         if (!(that.getAlgorithm().equalsIgnoreCase(getAlgorithm())))
   268         if (!(that.getAlgorithm().equalsIgnoreCase(getAlgorithm())))
   265             return false;
   269             return false;
   266         if (!(that.getFormat().equalsIgnoreCase("RAW")))
   270         if (!(that.getFormat().equalsIgnoreCase("RAW")))
   267             return false;
   271             return false;
   268         byte[] thatEncoded = that.getEncoded();
   272         byte[] thatEncoded = that.getEncoded();
   269         boolean ret = MessageDigest.isEqual(key, that.getEncoded());
   273         boolean ret = MessageDigest.isEqual(key, thatEncoded);
   270         java.util.Arrays.fill(thatEncoded, (byte)0x00);
   274         Arrays.fill(thatEncoded, (byte)0x00);
   271         return ret;
   275         return ret;
   272     }
   276     }
   273 
   277 
   274     /**
   278     /**
   275      * Replace the PBE key to be serialized.
   279      * Replace the PBE key to be serialized.