KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > security > realm > lib > HashHelper


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright Andy Armstrong, andy@tagish.com
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or 1any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA
19  *
20  * Initial developer: Andy Armstrong, andy@tagish.com
21  * --------------------------------------------------------------------------
22  * $Id: HashHelper.java,v 1.3 2004/04/22 13:09:07 benoitf Exp $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.jonas.security.realm.lib;
27
28 import java.security.MessageDigest JavaDoc;
29 import java.security.NoSuchAlgorithmException JavaDoc;
30
31 /**
32  * Methods to hash Strings. All the methods in here are static so HashHelper
33  * should never be instantiated.
34  * @author Andy Armstrong, <A HREF="mailto:andy@tagish.com">andy@tagish.com </A>
35  * @author Yann Petiot for the modifications
36  * @author Florent Benoit modifications for integration in JOnAS
37  */

38 public class HashHelper {
39
40     /**
41      * Constant for conversion of hex to string
42      */

43     private static final int HEX_CONSTANT = 0xFF;
44
45     /**
46      * Because of java 1.3, there are only 3 types of algorithms SHA == SHA-1
47      */

48     private static final String JavaDoc[] ALGORITHM = {"MD5", "MD2", "SHA-1", "SHA"};
49
50     /**
51      * Algorithm are recognized as this
52      */

53     private static final String JavaDoc[] SEPARATOR_ALGORITHM = {"MD5:", "MD2:", "SHA-1:", "SHA:"};
54
55     /**
56      * Algorithm are recognized as this too
57      */

58     private static final String JavaDoc[] SEPARATOR_ALGORITHM_BIS = {"{MD5}", "{MD2}", "{SHA-1}", "{SHA}"};
59
60     /**
61      * The default algorithm
62      */

63     public static final String JavaDoc DEFAULT_ALGO = "MD5";
64
65     /**
66      * Can't make this: all the methods are static
67      */

68     private HashHelper() {
69     }
70
71     /**
72      * In order to use a specified algorithm, it is necessary to check if it is
73      * in ALGORITHM[]
74      * @param algo the String to check if it's a valid algorithm
75      * @return boolean <ul><li>true if it's valid</li><li>false if it isn't
76      * </li></ul>
77      */

78     private static boolean isAValidAlgorithm(String JavaDoc algo) {
79         for (int i = 0; i < ALGORITHM.length; i++) {
80             if (algo.equalsIgnoreCase(ALGORITHM[i])) {
81                 return true;
82             }
83         }
84         return false;
85     }
86
87     /**
88      * Return the haspassword object from a string. It extracts algorithm and
89      * password from the string
90      * @param password contain password and algorithm
91      * @return the haspassword object
92      */

93     public static HashPassword getHashPassword(String JavaDoc password) {
94         String JavaDoc pass = null;
95         String JavaDoc algo = null;
96         //Check with the format ALGO:
97
for (int i = 0; i < ALGORITHM.length; i++) {
98             if (password.toUpperCase().startsWith(SEPARATOR_ALGORITHM[i])) {
99                 pass = password.substring(SEPARATOR_ALGORITHM[i].length());
100                 algo = password.substring(0, SEPARATOR_ALGORITHM[i].length() - 1);
101                 return new HashPassword(pass, algo);
102             }
103             if (password.toUpperCase().startsWith(SEPARATOR_ALGORITHM_BIS[i])) {
104                 pass = password.substring(SEPARATOR_ALGORITHM_BIS[i].length());
105                 algo = password.substring(1, SEPARATOR_ALGORITHM_BIS[i].length() - 1);
106                 return new HashPassword(pass, algo);
107             }
108         }
109
110         //Return a haspassword without algorithm (clear password)
111
return new HashPassword(password, null);
112     }
113
114     /**
115      * Turn a byte array into a char array containing a printable hex
116      * representation of the bytes. Each byte in the source array contributes a
117      * pair of hex digits to the output array.
118      * @param src the source array
119      * @return a char array containing a printable version of the source data
120      */

121     public static char[] hexDump(byte[] src) {
122         char[] buf = new char[src.length * 2];
123
124         for (int b = 0; b < src.length; b++) {
125             String JavaDoc byt = Integer.toHexString(src[b] & HEX_CONSTANT);
126
127             if (byt.length() < 2) {
128                 buf[b * 2 + 0] = '0';
129                 buf[b * 2 + 1] = byt.charAt(0);
130             } else {
131                 buf[b * 2 + 0] = byt.charAt(0);
132                 buf[b * 2 + 1] = byt.charAt(1);
133             }
134         }
135         return buf;
136     }
137
138     /**
139      * Zero the contents of the specified array. Typically used to erase
140      * temporary storage that has held plaintext passwords so that we don't
141      * leave them lying around in memory.
142      * @param pwd the array to zero
143      */

144     public static void smudge(char[] pwd) {
145         if (pwd != null) {
146             for (int b = 0; b < pwd.length; b++) {
147                 pwd[b] = 0;
148             }
149         }
150     }
151
152     /**
153      * Zero the contents of the specified array.
154      * @param pwd the array to zero
155      */

156     public static void smudge(byte[] pwd) {
157         if (pwd != null) {
158             for (int b = 0; b < pwd.length; b++) {
159                 pwd[b] = 0;
160             }
161         }
162     }
163
164     /**
165      * Performs the default algorithm hashing on the supplied password and
166      * return a char array containing the password as a printable string. The
167      * hash is computed on the low 8 bits of each character.
168      * @param pwd The password to hash
169      * @return a string representation of the hash password
170      * @throws NoSuchAlgorithmException if this is not a valid algorithm
171      */

172     public static String JavaDoc hashPassword(char[] pwd) throws NoSuchAlgorithmException JavaDoc {
173         return hashPassword(pwd, DEFAULT_ALGO);
174     }
175
176     /**
177      * Performs an algorithm specified by the user hashing on the supplied
178      * password and return a char array containing the encrypted password as a
179      * printable string. The hash is computed on the low 8 bits of each
180      * character.
181      * @param pwd The password to hash
182      * @param algo The type of Message Digest Algorithms
183      * @return a string representation of the hash password
184      * @throws NoSuchAlgorithmException if the algorithm can not be found
185      */

186     public static String JavaDoc hashPassword(char[] pwd, String JavaDoc algo) throws NoSuchAlgorithmException JavaDoc {
187
188         if (!isAValidAlgorithm(algo)) {
189             throw new NoSuchAlgorithmException JavaDoc("Your algorithm isn't valid or not yet supported.");
190         }
191         MessageDigest JavaDoc md = MessageDigest.getInstance(algo);
192         md.reset();
193
194         byte[] pwdb = new byte[pwd.length];
195         byte[] crypt = null;
196         for (int b = 0; b < pwd.length; b++) {
197             pwdb[b] = (byte) pwd[b];
198         }
199         crypt = md.digest(pwdb);
200         smudge(pwdb);
201         return new String JavaDoc(Base64.encode(crypt));
202     }
203
204     /**
205      * Performs an algorithm specified by the user hashing on the supplied
206      * password and return a char array containing the encrypted password as a
207      * printable string. The hash is computed on the low 8 bits of each
208      * character.
209      * @param string The password to hash
210      * @param algo The type of Message Digest Algorithms
211      * @return a string representation of the hash password
212      * @throws NoSuchAlgorithmException if the algorithm can not be found
213      */

214     public static String JavaDoc hashPassword(String JavaDoc string, String JavaDoc algo) throws NoSuchAlgorithmException JavaDoc {
215         return hashPassword(string.toCharArray(), algo);
216     }
217 }
Popular Tags