Home | History | Annotate | Download | only in spec
      1 /*
      2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 package javax.crypto.spec;
     27 
     28 import java.security.spec.KeySpec;
     29 
     30 /**
     31  * A user-chosen password that can be used with password-based encryption
     32  * (<i>PBE</i>).
     33  *
     34  * <p>The password can be viewed as some kind of raw key material, from which
     35  * the encryption mechanism that uses it derives a cryptographic key.
     36  *
     37  * <p>Different PBE mechanisms may consume different bits of each password
     38  * character. For example, the PBE mechanism defined in
     39  * <a href="http://www.ietf.org/rfc/rfc2898.txt">
     40  * PKCS #5</a> looks at only the low order 8 bits of each character, whereas
     41  * PKCS #12 looks at all 16 bits of each character.
     42  *
     43  * <p>You convert the password characters to a PBE key by creating an
     44  * instance of the appropriate secret-key factory. For example, a secret-key
     45  * factory for PKCS #5 will construct a PBE key from only the low order 8 bits
     46  * of each password character, whereas a secret-key factory for PKCS #12 will
     47  * take all 16 bits of each character.
     48  *
     49  * <p>Also note that this class stores passwords as char arrays instead of
     50  * <code>String</code> objects (which would seem more logical), because the
     51  * String class is immutable and there is no way to overwrite its
     52  * internal value when the password stored in it is no longer needed. Hence,
     53  * this class requests the password as a char array, so it can be overwritten
     54  * when done.
     55  *
     56  * @author Jan Luehe
     57  * @author Valerie Peng
     58  *
     59  * @see javax.crypto.SecretKeyFactory
     60  * @see PBEParameterSpec
     61  * @since 1.4
     62  */
     63 public class PBEKeySpec implements KeySpec {
     64 
     65     private char[] password;
     66     private byte[] salt = null;
     67     private int iterationCount = 0;
     68     private int keyLength = 0;
     69 
     70     /**
     71      * Constructor that takes a password. An empty char[] is used if
     72      * null is specified.
     73      *
     74      * <p> Note: <code>password</code> is cloned before it is stored in
     75      * the new <code>PBEKeySpec</code> object.
     76      *
     77      * @param password the password.
     78      */
     79     public PBEKeySpec(char[] password) {
     80         if ((password == null) || (password.length == 0)) {
     81             this.password = new char[0];
     82         } else {
     83             this.password = password.clone();
     84         }
     85     }
     86 
     87 
     88     /**
     89      * Constructor that takes a password, salt, iteration count, and
     90      * to-be-derived key length for generating PBEKey of variable-key-size
     91      * PBE ciphers.  An empty char[] is used if null is specified for
     92      * <code>password</code>.
     93      *
     94      * <p> Note: the <code>password</code> and <code>salt</code>
     95      * are cloned before they are stored in
     96      * the new <code>PBEKeySpec</code> object.
     97      *
     98      * @param password the password.
     99      * @param salt the salt.
    100      * @param iterationCount the iteration count.
    101      * @param keyLength the to-be-derived key length.
    102      * @exception NullPointerException if <code>salt</code> is null.
    103      * @exception IllegalArgumentException if <code>salt</code> is empty,
    104      * i.e. 0-length, <code>iterationCount</code> or
    105      * <code>keyLength</code> is not positive.
    106      */
    107     public PBEKeySpec(char[] password, byte[] salt, int iterationCount,
    108         int keyLength) {
    109         if ((password == null) || (password.length == 0)) {
    110             this.password = new char[0];
    111         } else {
    112             this.password = password.clone();
    113         }
    114         if (salt == null) {
    115             throw new NullPointerException("the salt parameter " +
    116                                             "must be non-null");
    117         } else if (salt.length == 0) {
    118             throw new IllegalArgumentException("the salt parameter " +
    119                                                 "must not be empty");
    120         } else {
    121             this.salt = salt.clone();
    122         }
    123         if (iterationCount<=0) {
    124             throw new IllegalArgumentException("invalid iterationCount value");
    125         }
    126         if (keyLength<=0) {
    127             throw new IllegalArgumentException("invalid keyLength value");
    128         }
    129         this.iterationCount = iterationCount;
    130         this.keyLength = keyLength;
    131     }
    132 
    133 
    134     /**
    135      * Constructor that takes a password, salt, iteration count for
    136      * generating PBEKey of fixed-key-size PBE ciphers. An empty
    137      * char[] is used if null is specified for <code>password</code>.
    138      *
    139      * <p> Note: the <code>password</code> and <code>salt</code>
    140      * are cloned before they are stored in the new
    141      * <code>PBEKeySpec</code> object.
    142      *
    143      * @param password the password.
    144      * @param salt the salt.
    145      * @param iterationCount the iteration count.
    146      * @exception NullPointerException if <code>salt</code> is null.
    147      * @exception IllegalArgumentException if <code>salt</code> is empty,
    148      * i.e. 0-length, or <code>iterationCount</code> is not positive.
    149      */
    150     public PBEKeySpec(char[] password, byte[] salt, int iterationCount) {
    151         if ((password == null) || (password.length == 0)) {
    152             this.password = new char[0];
    153         } else {
    154             this.password = password.clone();
    155         }
    156         if (salt == null) {
    157             throw new NullPointerException("the salt parameter " +
    158                                             "must be non-null");
    159         } else if (salt.length == 0) {
    160             throw new IllegalArgumentException("the salt parameter " +
    161                                                 "must not be empty");
    162         } else {
    163             this.salt = salt.clone();
    164         }
    165         if (iterationCount<=0) {
    166             throw new IllegalArgumentException("invalid iterationCount value");
    167         }
    168         this.iterationCount = iterationCount;
    169     }
    170 
    171     /**
    172      * Clears the internal copy of the password.
    173      *
    174      */
    175     public final void clearPassword() {
    176         if (password != null) {
    177             for (int i = 0; i < password.length; i++) {
    178                 password[i] = ' ';
    179             }
    180             password = null;
    181         }
    182     }
    183 
    184     /**
    185      * Returns a copy of the password.
    186      *
    187      * <p> Note: this method returns a copy of the password. It is
    188      * the caller's responsibility to zero out the password information after
    189      * it is no longer needed.
    190      *
    191      * @exception IllegalStateException if password has been cleared by
    192      * calling <code>clearPassword</code> method.
    193      * @return the password.
    194      */
    195     public final char[] getPassword() {
    196         if (password == null) {
    197             throw new IllegalStateException("password has been cleared");
    198         }
    199         return password.clone();
    200     }
    201 
    202     /**
    203      * Returns a copy of the salt or null if not specified.
    204      *
    205      * <p> Note: this method should return a copy of the salt. It is
    206      * the caller's responsibility to zero out the salt information after
    207      * it is no longer needed.
    208      *
    209      * @return the salt.
    210      */
    211     public final byte[] getSalt() {
    212         if (salt != null) {
    213             return salt.clone();
    214         } else {
    215             return null;
    216         }
    217     }
    218 
    219     /**
    220      * Returns the iteration count or 0 if not specified.
    221      *
    222      * @return the iteration count.
    223      */
    224     public final int getIterationCount() {
    225         return iterationCount;
    226     }
    227 
    228     /**
    229      * Returns the to-be-derived key length or 0 if not specified.
    230      *
    231      * <p> Note: this is used to indicate the preference on key length
    232      * for variable-key-size ciphers. The actual key size depends on
    233      * each provider's implementation.
    234      *
    235      * @return the to-be-derived key length.
    236      */
    237     public final int getKeyLength() {
    238         return keyLength;
    239     }
    240 }
    241