Home >> All >> cryptix >> jce >> provider >> [ keyfactory Javadoc ] |
Source code: cryptix/jce/provider/keyfactory/PBEKeyFactory.java
1 /* $Id: PBEKeyFactory.java,v 1.1 2000/06/09 21:37:31 pw Exp $ 2 * 3 * Copyright (C) 1995-2000 The Cryptix Foundation Limited. 4 * All rights reserved. 5 * 6 * Use, modification, copying and distribution of this software is subject 7 * the terms and conditions of the Cryptix General Licence. You should have 8 * received a copy of the Cryptix General License along with this library; 9 * if not, you can download a copy from http://www.cryptix.org/ . 10 */ 11 package cryptix.jce.provider.keyfactory; 12 13 14 import cryptix.jce.provider.key.RawSecretKey; 15 16 import java.lang.reflect.Constructor; 17 import java.lang.reflect.Array; 18 import java.lang.reflect.InvocationTargetException; 19 20 import java.security.InvalidKeyException; 21 22 import java.security.spec.InvalidKeySpecException; 23 import java.security.spec.KeySpec; 24 25 import javax.crypto.SecretKey; 26 import javax.crypto.SecretKeyFactorySpi; 27 import javax.crypto.spec.PBEKeySpec; 28 29 30 /** 31 * This is a KeyFactory for PBE. 32 * It converts key specs and secret keys into PBEKeys. 33 * It is based (as any cipher) on a service provider interface. 34 * This is SecretKeyFactorySpi as PBE ciphers are using 35 * secret key ciphers. 36 * 37 * @author: Josef Hartmann (jhartmann@bigfoot.com) 38 * @version: $Revision: 1.1 $ 39 */ 40 41 public final class PBEKeyFactory extends SecretKeyFactorySpi 42 { 43 44 /** Internal storage for the PBEKeySpec. */ 45 private PBEKeySpec pbeKeySpec = null; 46 47 /** 48 * This method generates a secret key based 49 * on the given KeySpec. 50 * Either decode data of the key or regenerate the key based 51 * on the keyspec. 52 * 53 * @param keySpec KeySpec Instance of PBEKeySpec 54 * @returns: SecretKey based on KeySpec. 55 * @exception: InvalidKeySpecException if something goes wrong. 56 */ 57 protected SecretKey engineGenerateSecret(KeySpec keySpec) 58 throws InvalidKeySpecException 59 { 60 // Check if parameter is valid. 61 if ((keySpec==null) || !(keySpec instanceof PBEKeySpec)) 62 { 63 // FIXME: Anything else to do here? 64 // We could do keySpec.getEncoded() 65 throw new InvalidKeySpecException( 66 "Cannot generate SecretKey using given KeySpec."); 67 } 68 else 69 { 70 // FIXME: We could get a KeySpec which is not a PBEKeySpec 71 // so it should be possible to convert it! 72 } 73 74 // keySpec is valid -> cast keySpec 75 pbeKeySpec = (PBEKeySpec) keySpec; 76 77 // create RawSecretKey using the keySpec. 78 RawSecretKey key = new RawSecretKey("PBE",new String(pbeKeySpec.getPassword()).getBytes()); 79 80 return key; 81 } 82 83 84 /** 85 * This method returns a key specification of the given secret key 86 * using the provided key spec class as the output format. 87 * 88 * 89 * @param key SecretKey The key to use for creating the key specification. 90 * @param keySpec Class The key format of the returning KeySpec value. 91 * @returns The key specification in the requested format. 92 * @exception InvalidKeySpecException If something goes wrong. 93 */ 94 protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec) 95 throws InvalidKeySpecException 96 { 97 if ((key==null)||(keySpec == null)) 98 { 99 throw new InvalidKeySpecException("Null parameter provided."); 100 } 101 102 Class specClass = null; 103 try 104 { 105 specClass = Class.forName("javax.crypto.spec.PBEKeySpec"); 106 } 107 catch (ClassNotFoundException cnfe) 108 { 109 throw new InvalidKeySpecException("Cannot create" 110 +" KeySpec class not found!"); 111 } 112 113 // Check if keySpec is the same as or a super class (interface) of 114 // PBEKeySpec. 115 116 if (keySpec.isAssignableFrom(specClass)) 117 { 118 119 byte [] keyData = key.getEncoded(); 120 char [] rawKeyData = new char[keyData.length]; 121 122 // use System.arraycopy? 123 for (int i=0; i<keyData.length; i++) 124 { 125 rawKeyData[i] = (char)(keyData[i]); 126 } 127 128 // Use reflection to detect constructor of keySpec and create it. 129 // FIXME: MAYBE JUST DO WHAT (PW) does in BlockParameters.java 130 // (jh) 131 132 Object [] initArgs = new Object[] {rawKeyData}; 133 134 // This is the parameter type the constructor should take. 135 Class [] constructorArgs = {char[].class}; 136 137 KeySpec pks = null; 138 139 // Get constructors. 140 try 141 { 142 Constructor specConstructor = 143 keySpec.getConstructor(constructorArgs); 144 145 pks = (KeySpec) specConstructor.newInstance(initArgs); 146 147 } 148 catch (InstantiationException e) 149 { 150 throw new InvalidKeySpecException("InvalidKeySpec."); 151 } 152 catch (IllegalAccessException e) 153 { 154 throw new InvalidKeySpecException("IllegalAccess."); 155 } 156 catch (IllegalArgumentException e) 157 { 158 throw new InvalidKeySpecException("Illegal constr. argument."); 159 } 160 catch (InvocationTargetException e) 161 { 162 throw new InvalidKeySpecException("InvocationTargetException."); 163 } 164 catch (NoSuchMethodException e) 165 { 166 throw new InvalidKeySpecException("Method not found."); 167 } 168 169 return pks; 170 } 171 else 172 { 173 throw new InvalidKeySpecException("Cannot assign to KeySpec."); 174 } 175 176 } 177 178 179 /** 180 * This method translates a secret key of an untrusted or 181 * unknown provider into a "valid" secret key. 182 * 183 * status: pending, not tested. 184 * 185 * @param key SecretKey Key to translate. 186 * @returns A secret key. 187 * @exception InvalidKeyException 188 */ 189 protected SecretKey engineTranslateKey(SecretKey key) 190 throws InvalidKeyException 191 { 192 if (key == null) 193 { 194 throw new InvalidKeyException(); 195 } 196 else 197 { 198 if ((key instanceof RawSecretKey)&&(key.getAlgorithm()=="PBE")) 199 { 200 // Nothing to do key is fine. 201 return key; 202 } 203 else 204 { 205 // create a key using PBEKeySpec 206 try 207 { 208 KeySpec tmpKs = this.engineGetKeySpec(key, null); 209 return engineGenerateSecret(tmpKs); 210 } 211 catch (InvalidKeySpecException ikse) 212 { 213 throw new InvalidKeyException("Translation not possible."); 214 } 215 216 } 217 218 } 219 220 // throw new InvalidKeyException(); 221 222 } 223 224 }