1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @author Alexander Y. Kleymenov 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @version $Revision$ 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*/ 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage javax.crypto.spec; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.spec.KeySpec; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.crypto.SecretKey; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A key specification for a <code>SecretKey</code> and also a secret key 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementation that is provider-independent. It can be used for raw secret 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * keys that can be specified as <code>byte[]</code>. 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class SecretKeySpec implements SecretKey, KeySpec, Serializable { 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The 5.0 spec. doesn't declare this serialVersionUID field 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // In order to be compatible it is explicitly declared here 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // for details see HARMONY-233 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 6577238317307289933L; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final byte[] key; 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final String algorithm; 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new <code>SecretKeySpec</code> for the specified key data and 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * algorithm name. 48ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the key data. 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param algorithm 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm name. 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the key data or the algorithm name is null or if the key 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * data is empty. 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SecretKeySpec(byte[] key, String algorithm) { 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key == null) { 5980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("key == null"); 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key.length == 0) { 6280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("key.length == 0"); 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (algorithm == null) { 6580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("algorithm == null"); 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.algorithm = algorithm; 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.key = new byte[key.length]; 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(key, 0, this.key, 0, key.length); 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new <code>SecretKeySpec</code> for the key data from the 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified buffer <code>key</code> starting at <code>offset</code> with 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * length <code>len</code> and the specified <code>algorithm</code> name. 77ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the key data. 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param offset 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset. 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param len 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the size of the key data. 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param algorithm 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm name. 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the key data or the algorithm name is null, the key data 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is empty or <code>offset</code> and <code>len</code> do not 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specify a valid chunk in the buffer <code>key</code>. 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ArrayIndexOutOfBoundsException 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if <code>offset</code> or <code>len</code> is negative. 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SecretKeySpec(byte[] key, int offset, int len, String algorithm) { 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key == null) { 9580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("key == null"); 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key.length == 0) { 9880a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("key.length == 0"); 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (len < 0 || offset < 0) { 10180a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new ArrayIndexOutOfBoundsException("len < 0 || offset < 0"); 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 10380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes if (key.length - offset < len) { 10480a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("key too short"); 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (algorithm == null) { 10780a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("algorithm == null"); 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.algorithm = algorithm; 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.key = new byte[len]; 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(key, offset, this.key, 0, len); 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the algorithm name. 116ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the algorithm name. 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getAlgorithm() { 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return algorithm; 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the name of the format used to encode the key. 125ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the format name "RAW". 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getFormat() { 1296aa068b481cc4cca7765ce90fdf32f3eb2b5a77cElliott Hughes return "RAW"; 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the encoded form of this secret key. 134ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the encoded form of this secret key. 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] getEncoded() { 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] result = new byte[key.length]; 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(key, 0, result, 0, key.length); 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the hash code of this <code>SecretKeySpec</code> object. 145ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the hash code. 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int hashCode() { 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int result = algorithm.length(); 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (byte element : key) { 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result += element; 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compares the specified object with this <code>SecretKeySpec</code> 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * instance. 160ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the object to compare. 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the algorithm name and key of both object are equal, 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise false. 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean equals(Object obj) { 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (obj == this) { 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(obj instanceof SecretKeySpec)) { 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecretKeySpec ks = (SecretKeySpec) obj; 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (algorithm.equalsIgnoreCase(ks.algorithm)) 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && (Arrays.equals(key, ks.key)); 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 179