KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > directory > ldapstudio > browser > core > model > Password


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  *
19  */

20
21 package org.apache.directory.ldapstudio.browser.core.model;
22
23
24 import java.security.MessageDigest JavaDoc;
25 import java.security.NoSuchAlgorithmException JavaDoc;
26 import java.security.SecureRandom JavaDoc;
27
28 import org.apache.directory.ldapstudio.browser.core.BrowserCoreMessages;
29 import org.apache.directory.ldapstudio.browser.core.utils.LdifUtils;
30 import org.apache.directory.ldapstudio.browser.core.utils.UnixCrypt;
31
32
33 public class Password
34 {
35
36     public static final String JavaDoc HASH_METHOD_SHA = "SHA"; //$NON-NLS-1$
37

38     public static final String JavaDoc HASH_METHOD_SSHA = "SSHA"; //$NON-NLS-1$
39

40     public static final String JavaDoc HASH_METHOD_MD5 = "MD5"; //$NON-NLS-1$
41

42     public static final String JavaDoc HASH_METHOD_SMD5 = "SMD5"; //$NON-NLS-1$
43

44     public static final String JavaDoc HASH_METHOD_CRYPT = "CRYPT"; //$NON-NLS-1$
45

46     public static final String JavaDoc HASH_METHOD_NO = BrowserCoreMessages.model__no_hash;
47
48     public static final String JavaDoc HASH_METHOD_UNSUPPORTED = BrowserCoreMessages.model__unsupported_hash;
49
50     String JavaDoc hashMethod;
51
52     byte[] hashedPassword;
53
54     byte[] salt;
55
56     String JavaDoc trash;
57
58
59     public Password( byte[] password )
60     {
61         this( LdifUtils.utf8decode( password ) );
62     }
63
64
65     public Password( String JavaDoc password )
66     {
67
68         if ( password == null )
69         {
70             throw new IllegalArgumentException JavaDoc( BrowserCoreMessages.model__empty_password );
71         }
72         else if ( password.indexOf( '{' ) == 0 && password.indexOf( '}' ) > 0 )
73         {
74             hashMethod = password.substring( password.indexOf( '{' ) + 1, password.indexOf( '}' ) );
75             String JavaDoc rest = password.substring( hashMethod.length() + 2 );
76
77             if ( HASH_METHOD_SHA.equals( hashMethod ) || HASH_METHOD_MD5.equals( hashMethod ) )
78             {
79                 hashedPassword = LdifUtils.base64decodeToByteArray( rest );
80                 salt = null;
81             }
82             else if ( HASH_METHOD_SSHA.equals( hashMethod ) )
83             {
84                 byte[] hashedPasswordWithSalt = LdifUtils.base64decodeToByteArray( rest );
85                 hashedPassword = new byte[20];
86                 salt = new byte[hashedPasswordWithSalt.length - hashedPassword.length];
87                 split( hashedPasswordWithSalt, hashedPassword, salt );
88             }
89             else if ( HASH_METHOD_SMD5.equals( hashMethod ) )
90             {
91                 byte[] hashedPasswordWithSalt = LdifUtils.base64decodeToByteArray( rest );
92                 hashedPassword = new byte[16];
93                 salt = new byte[hashedPasswordWithSalt.length - hashedPassword.length];
94                 split( hashedPasswordWithSalt, hashedPassword, salt );
95             }
96             else if ( HASH_METHOD_CRYPT.equals( hashMethod ) )
97             {
98                 byte[] saltWithPassword = LdifUtils.utf8encode( rest );
99                 salt = new byte[2];
100                 hashedPassword = new byte[saltWithPassword.length - salt.length];
101                 split( saltWithPassword, salt, hashedPassword );
102             }
103             else
104             {
105                 // throw new IllegalArgumentException("Unsupported hash method
106
// '"+hashMethod+"'");
107
// handle as plain text?
108
hashMethod = HASH_METHOD_UNSUPPORTED;
109                 trash = password;
110                 // salt = null;
111
}
112         }
113         else
114         {
115             // plain text
116
hashMethod = null;
117             hashedPassword = LdifUtils.utf8encode( password );
118             salt = null;
119         }
120     }
121
122
123     public Password( String JavaDoc hashMethod, String JavaDoc passwordAsPlaintext )
124     {
125
126         if ( !( hashMethod == null || HASH_METHOD_NO.equals( hashMethod ) || HASH_METHOD_SHA.equals( hashMethod )
127             || HASH_METHOD_SSHA.equals( hashMethod ) || HASH_METHOD_MD5.equals( hashMethod )
128             || HASH_METHOD_SMD5.equals( hashMethod ) || HASH_METHOD_CRYPT.equals( hashMethod ) ) )
129         {
130             throw new IllegalArgumentException JavaDoc( BrowserCoreMessages.model__unsupported_hash );
131         }
132         if ( passwordAsPlaintext == null )
133         {
134             throw new IllegalArgumentException JavaDoc( BrowserCoreMessages.model__empty_password );
135         }
136
137         // set hash method
138
if ( HASH_METHOD_NO.equals( hashMethod ) )
139         {
140             hashMethod = null;
141         }
142         this.hashMethod = hashMethod;
143
144         // set salt
145
if ( HASH_METHOD_SSHA.equals( hashMethod ) || HASH_METHOD_SMD5.equals( hashMethod ) )
146         {
147             this.salt = new byte[8];
148             new SecureRandom JavaDoc().nextBytes( this.salt );
149         }
150         else if ( HASH_METHOD_CRYPT.equals( hashMethod ) )
151         {
152             this.salt = new byte[2];
153             SecureRandom JavaDoc sr = new SecureRandom JavaDoc();
154             int i1 = sr.nextInt( 64 );
155             int i2 = sr.nextInt( 64 );
156             this.salt[0] = ( byte ) ( i1 < 12 ? ( i1 + '.' ) : i1 < 38 ? ( i1 + 'A' - 12 ) : ( i1 + 'a' - 38 ) );
157             this.salt[1] = ( byte ) ( i2 < 12 ? ( i2 + '.' ) : i2 < 38 ? ( i2 + 'A' - 12 ) : ( i2 + 'a' - 38 ) );
158         }
159         else
160         {
161             this.salt = null;
162         }
163
164         // digest
165
if ( HASH_METHOD_SHA.equals( hashMethod ) || HASH_METHOD_SSHA.equals( hashMethod ) )
166         {
167             this.hashedPassword = digest( HASH_METHOD_SHA, passwordAsPlaintext, this.salt );
168         }
169         else if ( HASH_METHOD_MD5.equals( hashMethod ) || HASH_METHOD_SMD5.equals( hashMethod ) )
170         {
171             this.hashedPassword = digest( HASH_METHOD_MD5, passwordAsPlaintext, this.salt );
172         }
173         else if ( HASH_METHOD_CRYPT.equals( hashMethod ) )
174         {
175             this.hashedPassword = crypt( passwordAsPlaintext, this.salt );
176         }
177         else if ( hashMethod == null )
178         {
179             this.hashedPassword = LdifUtils.utf8encode( passwordAsPlaintext );
180         }
181     }
182
183
184     public boolean verify( String JavaDoc testPasswordAsPlaintext )
185     {
186
187         if ( testPasswordAsPlaintext == null )
188         {
189             return false;
190         }
191
192         boolean verified = false;
193         if ( hashMethod == null )
194         {
195             verified = testPasswordAsPlaintext.equals( LdifUtils.utf8decode( hashedPassword ) );
196         }
197         else if ( HASH_METHOD_SHA.equals( hashMethod ) || HASH_METHOD_SSHA.equals( hashMethod ) )
198         {
199             byte[] hash = digest( HASH_METHOD_SHA, testPasswordAsPlaintext, this.salt );
200             verified = equals( hash, this.hashedPassword );
201         }
202         else if ( HASH_METHOD_MD5.equals( hashMethod ) || HASH_METHOD_SMD5.equals( hashMethod ) )
203         {
204             byte[] hash = digest( HASH_METHOD_MD5, testPasswordAsPlaintext, this.salt );
205             verified = equals( hash, this.hashedPassword );
206         }
207         else if ( HASH_METHOD_CRYPT.equals( hashMethod ) )
208         {
209             byte[] crypted = crypt( testPasswordAsPlaintext, this.salt );
210             verified = equals( crypted, this.hashedPassword );
211         }
212
213         return verified;
214     }
215
216
217     public String JavaDoc getHashMethod()
218     {
219         return this.hashMethod;
220     }
221
222
223     public byte[] getHashedPassword()
224     {
225         return hashedPassword;
226     }
227
228
229     public String JavaDoc getHashedPasswordAsHexString()
230     {
231         return LdifUtils.hexEncode( hashedPassword );
232     }
233
234
235     public byte[] getSalt()
236     {
237         return salt;
238     }
239
240
241     public String JavaDoc getSaltAsHexString()
242     {
243         return LdifUtils.hexEncode( salt );
244     }
245
246
247     public byte[] toBytes()
248     {
249         return LdifUtils.utf8encode( toString() );
250     }
251
252
253     public String JavaDoc toString()
254     {
255         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
256
257         if ( HASH_METHOD_UNSUPPORTED.equals( hashMethod ) )
258         {
259             sb.append( trash );
260         }
261         else if ( HASH_METHOD_CRYPT.equals( hashMethod ) )
262         {
263             sb.append( '{' ).append( hashMethod ).append( '}' );
264             sb.append( LdifUtils.utf8decode( salt ) );
265             sb.append( LdifUtils.utf8decode( hashedPassword ) );
266         }
267         else if ( hashMethod != null )
268         {
269             sb.append( '{' ).append( hashMethod ).append( '}' );
270             if ( salt != null )
271             {
272                 byte[] hashedPasswordWithSaltBytes = new byte[hashedPassword.length + salt.length];
273                 merge( hashedPasswordWithSaltBytes, hashedPassword, salt );
274                 sb.append( LdifUtils.base64encode( hashedPasswordWithSaltBytes ) );
275             }
276             else
277             {
278                 sb.append( LdifUtils.base64encode( hashedPassword ) );
279             }
280         }
281         else
282         {
283             sb.append( LdifUtils.utf8decode( hashedPassword ) );
284         }
285
286         return sb.toString();
287     }
288
289
290     private static void split( byte[] all, byte[] left, byte[] right )
291     {
292         System.arraycopy( all, 0, left, 0, left.length );
293         System.arraycopy( all, left.length, right, 0, right.length );
294     }
295
296
297     private static void merge( byte[] all, byte[] left, byte[] right )
298     {
299         System.arraycopy( left, 0, all, 0, left.length );
300         System.arraycopy( right, 0, all, left.length, right.length );
301     }
302
303
304     private static boolean equals( byte[] data1, byte[] data2 )
305     {
306         if ( data1 == data2 )
307             return true;
308         if ( data1 == null || data2 == null )
309             return false;
310         if ( data1.length != data2.length )
311             return false;
312         for ( int i = 0; i < data1.length; i++ )
313         {
314             if ( data1[i] != data2[i] )
315                 return false;
316         }
317         return true;
318     }
319
320
321     private static byte[] digest( String JavaDoc hashMethod, String JavaDoc password, byte[] salt )
322     {
323
324         byte[] passwordBytes = LdifUtils.utf8encode( password );
325         MessageDigest JavaDoc digest;
326         try
327         {
328             digest = MessageDigest.getInstance( hashMethod );
329         }
330         catch ( NoSuchAlgorithmException JavaDoc e1 )
331         {
332             return null;
333         }
334
335         if ( salt != null )
336         {
337             digest.update( passwordBytes );
338             digest.update( salt );
339             byte[] hashedPasswordBytes = digest.digest();
340             return hashedPasswordBytes;
341         }
342         else
343         {
344             byte[] hashedPasswordBytes = digest.digest( passwordBytes );
345             return hashedPasswordBytes;
346         }
347     }
348
349
350     private static byte[] crypt( String JavaDoc password, byte[] salt )
351     {
352         String JavaDoc saltWithCrypted = UnixCrypt.crypt( password, LdifUtils.utf8decode( salt ) );
353         String JavaDoc crypted = saltWithCrypted.substring( 2 );
354         return LdifUtils.utf8encode( crypted );
355     }
356
357 }
358
Popular Tags