1 /* $Id: PBEs.java,v 1.4 2000/01/20 14:59:23 gelderen 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 Licence along with this library; 9 * if not, you can download a copy from http://www.cryptix.org/ . 10 */ 11 package cryptix.jce.examples; 12 13 14 import java.io.FileInputStream; 15 import java.io.FileOutputStream; 16 import java.io.FileNotFoundException; 17 import java.io.IOException; 18 19 import java.security.InvalidAlgorithmParameterException; 20 import java.security.InvalidKeyException; 21 import java.security.Key; 22 import java.security.NoSuchAlgorithmException; 23 24 import java.security.spec.AlgorithmParameterSpec; 25 import java.security.spec.InvalidKeySpecException; 26 import java.security.spec.KeySpec; 27 28 import javax.crypto.Cipher; 29 import javax.crypto.CipherInputStream; 30 import javax.crypto.CipherOutputStream; 31 import javax.crypto.NoSuchPaddingException; 32 import javax.crypto.SecretKeyFactory; 33 34 import javax.crypto.spec.PBEKeySpec; 35 import javax.crypto.spec.PBEParameterSpec; 36 37 38 /** 39 * This class is intended to show usage of PBE algorithms. 40 * @version $Revision: 1.4 $ 41 * @author Josef Hartmann (jhartmann@bigfoot.com) 42 */ 43 public final class PBEs 44 { 45 private String algorithm = null; 46 private String filename = null; 47 private Key secretKey=null; 48 49 // Use this salt. 50 // In practice you should use a really random salt. 51 // For encryption and decryption you have to use the same salt. 52 /** salt. */ 53 private final byte [] salt = { 54 (byte)0x20, (byte)0x121, (byte)0x010, (byte)0x55, 55 (byte)0x83, (byte)0x001, (byte)0x101, (byte)0x91 56 }; 57 58 /** 59 * Iteration count for running hash function on password. 60 * E.g. md5(md5(md5(md5(password)))) 61 */ 62 private final int iterations = 20; 63 64 65 /** 66 * Constructor initialized with the algorithm name and 67 * the password for use in the PBE algorithm. 68 * 69 * @param algorithm String 70 * @param way String 71 * @param passphrase String 72 * @param filename String 73 */ PBEs(String algorithm, String passphrase)74 public PBEs(String algorithm, String passphrase) 75 { 76 // Store the algorithm. 77 this.algorithm = algorithm; 78 79 // Stripe passphrase into an array of chars. 80 char [] pw = new char[passphrase.length()]; 81 passphrase.getChars(0,passphrase.length(),pw,0); 82 83 // Create a KeySpec of the password chars. 84 KeySpec ks = new PBEKeySpec(pw); 85 86 // Create a secret key based on the passphrase 87 // for the specified algorithm. 88 SecretKeyFactory skf = null; 89 try 90 { 91 // Use a keyfactory in order to create a key 92 // for the PBE algorithm. 93 skf = SecretKeyFactory.getInstance(algorithm); 94 // Generate the secret key. 95 secretKey = skf.generateSecret(ks); 96 } 97 catch (NoSuchAlgorithmException nsae) 98 { 99 nsae.printStackTrace(); 100 } 101 catch (InvalidKeySpecException ikse) 102 { 103 ikse.printStackTrace(); 104 } 105 106 107 } 108 109 110 /** 111 * This method runs the PBE algorithm on the file. 112 * 113 * @param mode int decrypt or encrypt. 114 * @param filename String name of file to encrypt 115 * @return boolean 116 */ run(int mode, String filename)117 public boolean run(int mode, String filename) { 118 boolean ret = false; 119 120 // Create an algorithm parameter spec object based 121 // on the used salt and iterations. 122 AlgorithmParameterSpec aps = new PBEParameterSpec(salt, iterations); 123 Cipher cipher = null; 124 125 try 126 { 127 // Create the cipher object. 128 cipher = Cipher.getInstance(algorithm); 129 // Init cipher with mode, key and algorithm parameter spec. 130 cipher.init(mode, secretKey, aps); 131 ret = true; 132 } 133 catch (NoSuchAlgorithmException nsae) 134 { 135 nsae.printStackTrace(); 136 } 137 catch (NoSuchPaddingException nspe) 138 { 139 nspe.printStackTrace(); 140 } 141 catch (InvalidKeyException ike) 142 { 143 ike.printStackTrace(); 144 } 145 catch (InvalidAlgorithmParameterException iape) 146 { 147 iape.printStackTrace(); 148 } 149 150 if (ret) 151 ret=false; 152 else 153 return ret; 154 155 CipherOutputStream cOutStream = null; 156 CipherInputStream cInpStream = null; 157 FileInputStream fInput = null; 158 FileOutputStream fOutput = null; 159 160 try 161 { 162 if (mode == Cipher.ENCRYPT_MODE) { 163 164 fInput = new FileInputStream (filename); 165 fOutput = new FileOutputStream ( 166 filename+".PBEencrypted."+algorithm); 167 168 cOutStream = new CipherOutputStream(fOutput, cipher); 169 170 // Read input bytes into buffer and run them through the 171 // cipher stream. 172 byte[] buffer = new byte[8192]; 173 int length=0; 174 175 while ((length=fInput.read(buffer)) != -1) 176 { 177 cOutStream.write(buffer, 0, length); 178 } 179 180 // Close Streams. 181 fInput.close(); 182 cOutStream.close(); 183 ret = true; 184 185 } // if 186 else 187 { 188 // Cipher.DECRYPT_MODE 189 // Here we are in decryption mode. 190 // CipherInputStream cInpStream=null; 191 // Open file containing encrypted data. 192 fInput = new FileInputStream( 193 filename+".PBEencrypted."+algorithm); 194 195 cInpStream = new CipherInputStream(fInput,cipher); 196 197 fOutput = new FileOutputStream( 198 filename+".PBEdecrypted."+algorithm); 199 200 // Read bytes and run them through cipher and 201 // store them to file back again. 202 byte[] buffer=new byte[8192]; 203 int length=0; 204 205 while ((length=cInpStream.read(buffer)) != -1) { 206 fOutput.write(buffer, 0, length); 207 } 208 209 // Close streams. 210 cInpStream.close(); 211 fOutput.close(); 212 ret = true; 213 } 214 } 215 catch (FileNotFoundException fnfe) 216 { 217 fnfe.printStackTrace(); 218 return false; 219 } 220 catch (IOException ioe) 221 { 222 ioe.printStackTrace(); 223 return false; 224 } 225 226 return ret; 227 } 228 } 229