Save This Page
Home » openjdk-7 » javax » crypto » spec » [javadoc | source]
    1   /*
    2    * Copyright (c) 1998, 2007, 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.io.UnsupportedEncodingException;
   29   import java.security.Key;
   30   import java.security.spec.KeySpec;
   31   import javax.crypto.SecretKey;
   32   
   33   /**
   34    * This class specifies a secret key in a provider-independent fashion.
   35    *
   36    * <p>It can be used to construct a <code>SecretKey</code> from a byte array,
   37    * without having to go through a (provider-based)
   38    * <code>SecretKeyFactory</code>.
   39    *
   40    * <p>This class is only useful for raw secret keys that can be represented as
   41    * a byte array and have no key parameters associated with them, e.g., DES or
   42    * Triple DES keys.
   43    *
   44    * @author Jan Luehe
   45    *
   46    * @see javax.crypto.SecretKey
   47    * @see javax.crypto.SecretKeyFactory
   48    * @since 1.4
   49    */
   50   public class SecretKeySpec implements KeySpec, SecretKey {
   51   
   52       private static final long serialVersionUID = 6577238317307289933L;
   53   
   54       /**
   55        * The secret key.
   56        *
   57        * @serial
   58        */
   59       private byte[] key;
   60   
   61       /**
   62        * The name of the algorithm associated with this key.
   63        *
   64        * @serial
   65        */
   66       private String algorithm;
   67   
   68       /**
   69        * Constructs a secret key from the given byte array.
   70        *
   71        * <p>This constructor does not check if the given bytes indeed specify a
   72        * secret key of the specified algorithm. For example, if the algorithm is
   73        * DES, this constructor does not check if <code>key</code> is 8 bytes
   74        * long, and also does not check for weak or semi-weak keys.
   75        * In order for those checks to be performed, an algorithm-specific
   76        * <i>key specification</i> class (in this case:
   77        * {@link DESKeySpec DESKeySpec})
   78        * should be used.
   79        *
   80        * @param key the key material of the secret key. The contents of
   81        * the array are copied to protect against subsequent modification.
   82        * @param algorithm the name of the secret-key algorithm to be associated
   83        * with the given key material.
   84        * See Appendix A in the <a href=
   85        *   "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
   86        * Java Cryptography Architecture Reference Guide</a>
   87        * for information about standard algorithm names.
   88        * @exception IllegalArgumentException if <code>algorithm</code>
   89        * is null or <code>key</code> is null or empty.
   90        */
   91       public SecretKeySpec(byte[] key, String algorithm) {
   92           if (key == null || algorithm == null) {
   93               throw new IllegalArgumentException("Missing argument");
   94           }
   95           if (key.length == 0) {
   96               throw new IllegalArgumentException("Empty key");
   97           }
   98           this.key = (byte[])key.clone();
   99           this.algorithm = algorithm;
  100       }
  101   
  102       /**
  103        * Constructs a secret key from the given byte array, using the first
  104        * <code>len</code> bytes of <code>key</code>, starting at
  105        * <code>offset</code> inclusive.
  106        *
  107        * <p> The bytes that constitute the secret key are
  108        * those between <code>key[offset]</code> and
  109        * <code>key[offset+len-1]</code> inclusive.
  110        *
  111        * <p>This constructor does not check if the given bytes indeed specify a
  112        * secret key of the specified algorithm. For example, if the algorithm is
  113        * DES, this constructor does not check if <code>key</code> is 8 bytes
  114        * long, and also does not check for weak or semi-weak keys.
  115        * In order for those checks to be performed, an algorithm-specific key
  116        * specification class (in this case:
  117        * {@link DESKeySpec DESKeySpec})
  118        * must be used.
  119        *
  120        * @param key the key material of the secret key. The first
  121        * <code>len</code> bytes of the array beginning at
  122        * <code>offset</code> inclusive are copied to protect
  123        * against subsequent modification.
  124        * @param offset the offset in <code>key</code> where the key material
  125        * starts.
  126        * @param len the length of the key material.
  127        * @param algorithm the name of the secret-key algorithm to be associated
  128        * with the given key material.
  129        * See Appendix A in the <a href=
  130        *   "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
  131        * Java Cryptography Architecture Reference Guide</a>
  132        * for information about standard algorithm names.
  133        * @exception IllegalArgumentException if <code>algorithm</code>
  134        * is null or <code>key</code> is null, empty, or too short,
  135        * i.e. <code>key.length-offset<len</code>.
  136        * @exception ArrayIndexOutOfBoundsException is thrown if
  137        * <code>offset</code> or <code>len</code> index bytes outside the
  138        * <code>key</code>.
  139        */
  140       public SecretKeySpec(byte[] key, int offset, int len, String algorithm) {
  141           if (key == null || algorithm == null) {
  142               throw new IllegalArgumentException("Missing argument");
  143           }
  144           if (key.length == 0) {
  145               throw new IllegalArgumentException("Empty key");
  146           }
  147           if (key.length-offset < len) {
  148               throw new IllegalArgumentException
  149                   ("Invalid offset/length combination");
  150           }
  151           if (len < 0) {
  152               throw new ArrayIndexOutOfBoundsException("len is negative");
  153           }
  154           this.key = new byte[len];
  155           System.arraycopy(key, offset, this.key, 0, len);
  156           this.algorithm = algorithm;
  157       }
  158   
  159       /**
  160        * Returns the name of the algorithm associated with this secret key.
  161        *
  162        * @return the secret key algorithm.
  163        */
  164       public String getAlgorithm() {
  165           return this.algorithm;
  166       }
  167   
  168       /**
  169        * Returns the name of the encoding format for this secret key.
  170        *
  171        * @return the string "RAW".
  172        */
  173       public String getFormat() {
  174           return "RAW";
  175       }
  176   
  177       /**
  178        * Returns the key material of this secret key.
  179        *
  180        * @return the key material. Returns a new array
  181        * each time this method is called.
  182        */
  183       public byte[] getEncoded() {
  184           return (byte[])this.key.clone();
  185       }
  186   
  187       /**
  188        * Calculates a hash code value for the object.
  189        * Objects that are equal will also have the same hashcode.
  190        */
  191       public int hashCode() {
  192           int retval = 0;
  193           for (int i = 1; i < this.key.length; i++) {
  194               retval += this.key[i] * i;
  195           }
  196           if (this.algorithm.equalsIgnoreCase("TripleDES"))
  197               return (retval ^= "desede".hashCode());
  198           else
  199               return (retval ^= this.algorithm.toLowerCase().hashCode());
  200       }
  201   
  202      /**
  203        * Tests for equality between the specified object and this
  204        * object. Two SecretKeySpec objects are considered equal if
  205        * they are both SecretKey instances which have the
  206        * same case-insensitive algorithm name and key encoding.
  207        *
  208        * @param obj the object to test for equality with this object.
  209        *
  210        * @return true if the objects are considered equal, false if
  211        * <code>obj</code> is null or otherwise.
  212        */
  213       public boolean equals(Object obj) {
  214           if (this == obj)
  215               return true;
  216   
  217           if (!(obj instanceof SecretKey))
  218               return false;
  219   
  220           String thatAlg = ((SecretKey)obj).getAlgorithm();
  221           if (!(thatAlg.equalsIgnoreCase(this.algorithm))) {
  222               if ((!(thatAlg.equalsIgnoreCase("DESede"))
  223                    || !(this.algorithm.equalsIgnoreCase("TripleDES")))
  224                   && (!(thatAlg.equalsIgnoreCase("TripleDES"))
  225                       || !(this.algorithm.equalsIgnoreCase("DESede"))))
  226               return false;
  227           }
  228   
  229           byte[] thatKey = ((SecretKey)obj).getEncoded();
  230   
  231           return java.util.Arrays.equals(this.key, thatKey);
  232       }
  233   }

Save This Page
Home » openjdk-7 » javax » crypto » spec » [javadoc | source]