src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java

Print this page




  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 package com.sun.crypto.provider;
  27 
  28 import java.io.*;
  29 import java.nio.ByteBuffer;
  30 import java.nio.CharBuffer;
  31 import java.nio.charset.Charset;
  32 import java.util.Arrays;
  33 import java.security.KeyRep;
  34 import java.security.GeneralSecurityException;
  35 import java.security.InvalidKeyException;
  36 import java.security.NoSuchAlgorithmException;

  37 import java.security.spec.InvalidKeySpecException;
  38 import javax.crypto.Mac;
  39 import javax.crypto.SecretKey;
  40 import javax.crypto.spec.PBEKeySpec;
  41 import javax.crypto.spec.SecretKeySpec;
  42 
  43 /**
  44  * This class represents a PBE key derived using PBKDF2 defined
  45  * in PKCS#5 v2.0. meaning that
  46  * 1) the password must consist of characters which will be converted
  47  *    to bytes using UTF-8 character encoding.
  48  * 2) salt, iteration count, and to be derived key length are supplied
  49  *
  50  * @author Valerie Peng
  51  *
  52  */
  53 final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
  54 
  55     static final long serialVersionUID = -2234868909660948157L;
  56 


  90         // Convert the password from char[] to byte[]
  91         byte[] passwdBytes = getPasswordBytes(this.passwd);
  92 
  93         this.salt = keySpec.getSalt();
  94         if (salt == null) {
  95             throw new InvalidKeySpecException("Salt not found");
  96         }
  97         this.iterCount = keySpec.getIterationCount();
  98         if (iterCount == 0) {
  99             throw new InvalidKeySpecException("Iteration count not found");
 100         } else if (iterCount < 0) {
 101             throw new InvalidKeySpecException("Iteration count is negative");
 102         }
 103         int keyLength = keySpec.getKeyLength();
 104         if (keyLength == 0) {
 105             throw new InvalidKeySpecException("Key length not found");
 106         } else if (keyLength == 0) {
 107             throw new InvalidKeySpecException("Key length is negative");
 108         }
 109         try {
 110             this.prf = Mac.getInstance(prfAlgo, new SunJCE());
 111         } catch (NoSuchAlgorithmException nsae) {
 112             // not gonna happen; re-throw just in case
 113             InvalidKeySpecException ike = new InvalidKeySpecException();
 114             ike.initCause(nsae);
 115             throw ike;
 116         }
 117         this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength);
 118     }
 119 
 120     private static byte[] deriveKey(Mac prf, byte[] password, byte[] salt,
 121                                     int iterCount, int keyLengthInBit) {
 122         int keyLength = keyLengthInBit/8;
 123         byte[] key = new byte[keyLength];
 124         try {
 125             int hlen = prf.getMacLength();
 126             int intL = (keyLength + hlen - 1)/hlen; // ceiling
 127             int intR = keyLength - (intL - 1)*hlen; // residue
 128             byte[] ui = new byte[hlen];
 129             byte[] ti = new byte[hlen];
 130             SecretKey macKey = new SecretKeySpec(password, prf.getAlgorithm());




  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 package com.sun.crypto.provider;
  27 
  28 import java.io.*;
  29 import java.nio.ByteBuffer;
  30 import java.nio.CharBuffer;
  31 import java.nio.charset.Charset;
  32 import java.util.Arrays;
  33 import java.security.KeyRep;
  34 import java.security.GeneralSecurityException;
  35 import java.security.InvalidKeyException;
  36 import java.security.NoSuchAlgorithmException;
  37 import java.security.NoSuchProviderException;
  38 import java.security.spec.InvalidKeySpecException;
  39 import javax.crypto.Mac;
  40 import javax.crypto.SecretKey;
  41 import javax.crypto.spec.PBEKeySpec;
  42 import javax.crypto.spec.SecretKeySpec;
  43 
  44 /**
  45  * This class represents a PBE key derived using PBKDF2 defined
  46  * in PKCS#5 v2.0. meaning that
  47  * 1) the password must consist of characters which will be converted
  48  *    to bytes using UTF-8 character encoding.
  49  * 2) salt, iteration count, and to be derived key length are supplied
  50  *
  51  * @author Valerie Peng
  52  *
  53  */
  54 final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
  55 
  56     static final long serialVersionUID = -2234868909660948157L;
  57 


  91         // Convert the password from char[] to byte[]
  92         byte[] passwdBytes = getPasswordBytes(this.passwd);
  93 
  94         this.salt = keySpec.getSalt();
  95         if (salt == null) {
  96             throw new InvalidKeySpecException("Salt not found");
  97         }
  98         this.iterCount = keySpec.getIterationCount();
  99         if (iterCount == 0) {
 100             throw new InvalidKeySpecException("Iteration count not found");
 101         } else if (iterCount < 0) {
 102             throw new InvalidKeySpecException("Iteration count is negative");
 103         }
 104         int keyLength = keySpec.getKeyLength();
 105         if (keyLength == 0) {
 106             throw new InvalidKeySpecException("Key length not found");
 107         } else if (keyLength == 0) {
 108             throw new InvalidKeySpecException("Key length is negative");
 109         }
 110         try {
 111             this.prf = Mac.getInstance(prfAlgo);
 112         } catch (NoSuchAlgorithmException nsae) {
 113             // not gonna happen; re-throw just in case
 114             InvalidKeySpecException ike = new InvalidKeySpecException();
 115             ike.initCause(nsae);
 116             throw ike;
 117         }
 118         this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength);
 119     }
 120 
 121     private static byte[] deriveKey(Mac prf, byte[] password, byte[] salt,
 122                                     int iterCount, int keyLengthInBit) {
 123         int keyLength = keyLengthInBit/8;
 124         byte[] key = new byte[keyLength];
 125         try {
 126             int hlen = prf.getMacLength();
 127             int intL = (keyLength + hlen - 1)/hlen; // ceiling
 128             int intR = keyLength - (intL - 1)*hlen; // residue
 129             byte[] ui = new byte[hlen];
 130             byte[] ti = new byte[hlen];
 131             SecretKey macKey = new SecretKeySpec(password, prf.getAlgorithm());