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