KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > java > security > MD5


1 package org.apache.java.security;
2
3 /*
4  * Copyright 2001-2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License")
7  * you may not use this file except in compliance with the License.
8  * 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, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 /**
20  * This class implements the Message Digest 5 algorithm (MD5) as
21  * defined in RFC-1321.
22  *
23  * <p><b>Note:</b> even if standard Java 1.1 APIs already provide a
24  * MD5 implementation, this class is used on those Java runtime
25  * environments (like Kaffe) where the package
26  * <code>java.security</code> is highly improbable to be found.
27  *
28  * @author <a HREF="mailto:stefano@apache.org">Stefano Mazzocchi</a>
29  * @version $Id: MD5.java,v 1.2.2.2 2004/05/20 03:03:54 seade Exp $
30  * @deprecated Use the java.security package.
31  */

32 public final class MD5
33     extends MessageDigest
34 {
35     private long counter;
36     private int reminder;
37     private byte buffer[];
38     private int state[];
39     private int x[];
40
41     /*********************** MD5 Functions ***********************/
42
43     // 16 * 4 bytes
44
static byte padding[] =
45     {
46         (byte) 0x80,
47         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
51     };
52
53     /*********************** Self Test ***********************/
54
55     private static String JavaDoc[] messages =
56     {
57         "",
58         "a",
59         "abc",
60         "message digest",
61         "abcdefghijklmnopqrstuvwxyz",
62         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
63         "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
64     };
65
66     private static String JavaDoc[] digests =
67     {
68         "d41d8cd98f00b204e9800998ecf8427e",
69         "0cc175b9c0f1b6a831c399e269772661",
70         "900150983cd24fb0d6963f7d28e17f72",
71         "f96b697d7cb7938d525a2f31aaf161d0",
72         "c3fcd3d76192e4007dfb496cca67e13b",
73         "d174ab98d277d9f5a5611c2c9f419d9f",
74         "57edf4a22be3c955ac49da2e2107b67a",
75     };
76
77
78     /**
79      * Creates the algorithm and reset its state.
80      */

81     public MD5()
82     {
83         super();
84     }
85
86     /**
87      * Append another block of specified length to the message
88      * starting at the given offset.
89      *
90      * @param block A byte[].
91      * @param offset An int.
92      * @param length An int.
93      */

94     public void append(byte[] block,
95                        int offset,
96                        int length)
97     {
98         while (true)
99         {
100             if (length >= reminder)
101             {
102                 System.arraycopy(block, offset, buffer,
103                                  (int) (counter & 63L), reminder);
104                 transform(buffer);
105                 counter += reminder;
106                 offset += reminder;
107                 length -= reminder;
108                 reminder = 64;
109             }
110             else
111             {
112                 System.arraycopy(block, offset, buffer,
113                                  (int) (counter & 63L), length);
114                 counter += length;
115                 reminder -= length;
116                 break;
117             }
118         }
119     }
120
121     /*********************** Byte/Int utilities ***********************/
122
123     /**
124      * Converts a 64-byte array into a 16-int array.
125      *
126      * @param in A byte[].
127      * @param out An int[].
128      */

129     private static void byte2int(byte[] in,
130                                  int[] out)
131     {
132         for (int inpos = 0, outpos = 0; outpos < 16; outpos++)
133         {
134             out[outpos] = ((((int) (in[inpos++] & 0xff))) |
135                            (((int) (in[inpos++] & 0xff)) << 8) |
136                            (((int) (in[inpos++] & 0xff)) << 16) |
137                            (((int) (in[inpos++] & 0xff)) << 24));
138         }
139     }
140
141     /**
142      * Appends a message block with specified length starting from the
143      * given offset, and return its message digest.
144      *
145      * @param block A byte[].
146      * @param offset An int.
147      * @param length An int.
148      */

149     public byte[] digest(byte[] block,
150                          int offset,
151                          int length)
152     {
153         this.append(block, offset, length);
154
155         byte[] bits = toBytes(counter << 3);
156         byte[] digest = new byte[16];
157
158         if (reminder > 8)
159         {
160             append(padding, 0, reminder - 8);
161         }
162         else
163         {
164             append(padding, 0, 64 + (reminder - 8));
165         }
166
167         append(bits, 0, 8);
168
169         int2byte(state, digest);
170
171         this.reset();
172         return digest;
173     }
174
175     /*
176      * Method F.
177      *
178      * @param x An int.
179      * @param y An int.
180      * @param z An int.
181      * @return An int.
182      */

183     static private int F(int x,
184                          int y,
185                          int z)
186     {
187         return (z ^ (x & (y^z)));
188     }
189
190     /*
191      * Method FF.
192      *
193      * @param a An int.
194      * @param b An int.
195      * @param c An int.
196      * @param d An int.
197      * @param x An int.
198      * @param s An int.
199      * @param ac An int.
200      * @return An int.
201      */

202     static private int FF(int a,
203                           int b,
204                           int c,
205                           int d,
206                           int x,
207                           int s,
208                           int ac)
209     {
210         a += x + ac + F(b,c,d);
211         a = (a << s | a >>> -s);
212         return a + b;
213     }
214
215     /*
216      * Method G.
217      *
218      * @param x An int.
219      * @param y An int.
220      * @param z An int.
221      * @return An int.
222      */

223     static private int G(int x,
224                          int y,
225                          int z)
226     {
227         return (y ^ (z & (x^y)));
228     }
229
230     /*
231      * Method GG.
232      *
233      * @param a An int.
234      * @param b An int.
235      * @param c An int.
236      * @param d An int.
237      * @param x An int.
238      * @param s An int.
239      * @param ac An int.
240      * @return An int.
241      */

242     static private int GG(int a,
243                           int b,
244                           int c,
245                           int d,
246                           int x,
247                           int s,
248                           int ac)
249     {
250         a += x + ac + G(b,c,d);
251         a = (a << s | a >>> -s);
252         return a + b;
253     }
254
255     /*
256      * Method H.
257      *
258      * @param x An int.
259      * @param y An int.
260      * @param z An int.
261      * @return An int.
262      */

263     static private int H(int x,
264                          int y,
265                          int z)
266     {
267         return (x ^ y ^ z);
268     }
269
270     /*
271      * Method HH.
272      *
273      * @param a An int.
274      * @param b An int.
275      * @param c An int.
276      * @param d An int.
277      * @param x An int.
278      * @param s An int.
279      * @param ac An int.
280      * @return An int.
281      */

282     static private int HH(int a,
283                           int b,
284                           int c,
285                           int d,
286                           int x,
287                           int s,
288                           int ac)
289     {
290         a += x + ac + H(b,c,d);
291         a = (a << s | a >>> -s);
292         return a + b;
293     }
294
295     /*
296      * Method I.
297      *
298      * @param x An int.
299      * @param y An int.
300      * @param z An int.
301      * @return An int.
302      */

303     static private int I(int x,
304                          int y,
305                          int z)
306     {
307         return (y ^ (x | ~z));
308     }
309
310     /*
311      * Method II.
312      *
313      * @param a An int.
314      * @param b An int.
315      * @param c An int.
316      * @param d An int.
317      * @param x An int.
318      * @param s An int.
319      * @param ac An int.
320      * @return An int.
321      */

322     static private int II(int a,
323                           int b,
324                           int c,
325                           int d,
326                           int x,
327                           int s,
328                           int ac)
329     {
330         a += x + ac + I(b,c,d);
331         a = (a << s | a >>> -s);
332         return a + b;
333     }
334
335     /**
336      * Converts a 4-int array into a 16-byte array.
337      *
338      * @param in An int[].
339      * @param out A byte[].
340      */

341     private static void int2byte(int[] in,
342                                  byte[] out)
343     {
344         for (int inpos = 0, outpos = 0; inpos < 4; inpos++)
345         {
346             out[outpos++] = (byte) (in[inpos] & 0xff);
347             out[outpos++] = (byte) ((in[inpos] >>> 8) & 0xff);
348             out[outpos++] = (byte) ((in[inpos] >>> 16) & 0xff);
349             out[outpos++] = (byte) ((in[inpos] >>> 24) & 0xff);
350         }
351     }
352
353     /*
354      * Main routine, for testing purposes only.
355      *
356      * @param ignored A String[] with the command line arguments.
357      */

358     public static final void main(String JavaDoc[] ignored)
359     {
360         MD5 md5 = new MD5();
361
362         for (int i = 0; i < messages.length; i++)
363         {
364             String JavaDoc digest = org.apache.java.lang.Bytes.toString(
365                 md5.digest(messages[i].getBytes()));
366             System.out.println("Computed: " + digest);
367             System.out.println("Correct: " + digests[i]);
368             if (digest.equalsIgnoreCase(digests[i]))
369             {
370                 System.out.println("Test " + i + " passed.");
371             }
372             else
373             {
374                 System.out.println("Test " + i + " failed.");
375             }
376         }
377     }
378
379     /**
380      * Resets the state of the class. <b>Beware</b>: calling this
381      * method erases all data previously inserted.
382      */

383     public void reset()
384     {
385         buffer = new byte[64];
386         state = new int[4];
387         x = new int[16];
388
389         state[0] = 0x67452301;
390         state[1] = 0xefcdab89;
391         state[2] = 0x98badcfe;
392         state[3] = 0x10325476;
393
394         counter = 0;
395         reminder = 64;
396     }
397
398     /**
399      * Converts a long to a 8-byte array using low order first.
400      *
401      * @param n A long.
402      * @return A byte[].
403      */

404     public static byte[] toBytes(long n)
405     {
406         byte[] b = new byte[8];
407
408         b[0] = (byte) (n);
409         n >>>= 8;
410         b[1] = (byte) (n);
411         n >>>= 8;
412         b[2] = (byte) (n);
413         n >>>= 8;
414         b[3] = (byte) (n);
415         n >>>= 8;
416         b[4] = (byte) (n);
417         n >>>= 8;
418         b[5] = (byte) (n);
419         n >>>= 8;
420         b[6] = (byte) (n);
421         n >>>= 8;
422         b[7] = (byte) (n);
423
424         return b;
425     }
426
427     /*
428      * TODO: Document.
429      *
430      * @param buffer A byte[].
431      */

432     private void transform(byte[] buffer)
433     {
434         int a, b, c, d;
435
436         byte2int(buffer, x);
437
438         a = state[0];
439         b = state[1];
440         c = state[2];
441         d = state[3];
442
443         a = FF(a, b, c, d, x[ 0], 7, 0xd76aa478);
444         d = FF(d, a, b, c, x[ 1], 12, 0xe8c7b756);
445         c = FF(c, d, a, b, x[ 2], 17, 0x242070db);
446         b = FF(b, c, d, a, x[ 3], 22, 0xc1bdceee);
447         a = FF(a, b, c, d, x[ 4], 7, 0xf57c0faf);
448         d = FF(d, a, b, c, x[ 5], 12, 0x4787c62a);
449         c = FF(c, d, a, b, x[ 6], 17, 0xa8304613);
450         b = FF(b, c, d, a, x[ 7], 22, 0xfd469501);
451         a = FF(a, b, c, d, x[ 8], 7, 0x698098d8);
452         d = FF(d, a, b, c, x[ 9], 12, 0x8b44f7af);
453         c = FF(c, d, a, b, x[10], 17, 0xffff5bb1);
454         b = FF(b, c, d, a, x[11], 22, 0x895cd7be);
455         a = FF(a, b, c, d, x[12], 7, 0x6b901122);
456         d = FF(d, a, b, c, x[13], 12, 0xfd987193);
457         c = FF(c, d, a, b, x[14], 17, 0xa679438e);
458         b = FF(b, c, d, a, x[15], 22, 0x49b40821);
459
460         a = GG(a, b, c, d, x[ 1], 5, 0xf61e2562);
461         d = GG(d, a, b, c, x[ 6], 9, 0xc040b340);
462         c = GG(c, d, a, b, x[11], 14, 0x265e5a51);
463         b = GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);
464         a = GG(a, b, c, d, x[ 5], 5, 0xd62f105d);
465         d = GG(d, a, b, c, x[10], 9, 0x2441453);
466         c = GG(c, d, a, b, x[15], 14, 0xd8a1e681);
467         b = GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);
468         a = GG(a, b, c, d, x[ 9], 5, 0x21e1cde6);
469         d = GG(d, a, b, c, x[14], 9, 0xc33707d6);
470         c = GG(c, d, a, b, x[ 3], 14, 0xf4d50d87);
471         b = GG(b, c, d, a, x[ 8], 20, 0x455a14ed);
472         a = GG(a, b, c, d, x[13], 5, 0xa9e3e905);
473         d = GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8);
474         c = GG(c, d, a, b, x[ 7], 14, 0x676f02d9);
475         b = GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);
476
477         a = HH(a, b, c, d, x[ 5], 4, 0xfffa3942);
478         d = HH(d, a, b, c, x[ 8], 11, 0x8771f681);
479         c = HH(c, d, a, b, x[11], 16, 0x6d9d6122);
480         b = HH(b, c, d, a, x[14], 23, 0xfde5380c);
481         a = HH(a, b, c, d, x[ 1], 4, 0xa4beea44);
482         d = HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9);
483         c = HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60);
484         b = HH(b, c, d, a, x[10], 23, 0xbebfbc70);
485         a = HH(a, b, c, d, x[13], 4, 0x289b7ec6);
486         d = HH(d, a, b, c, x[ 0], 11, 0xeaa127fa);
487         c = HH(c, d, a, b, x[ 3], 16, 0xd4ef3085);
488         b = HH(b, c, d, a, x[ 6], 23, 0x4881d05);
489         a = HH(a, b, c, d, x[ 9], 4, 0xd9d4d039);
490         d = HH(d, a, b, c, x[12], 11, 0xe6db99e5);
491         c = HH(c, d, a, b, x[15], 16, 0x1fa27cf8);
492         b = HH(b, c, d, a, x[ 2], 23, 0xc4ac5665);
493
494         a = II(a, b, c, d, x[ 0], 6, 0xf4292244);
495         d = II(d, a, b, c, x[ 7], 10, 0x432aff97);
496         c = II(c, d, a, b, x[14], 15, 0xab9423a7);
497         b = II(b, c, d, a, x[ 5], 21, 0xfc93a039);
498         a = II(a, b, c, d, x[12], 6, 0x655b59c3);
499         d = II(d, a, b, c, x[ 3], 10, 0x8f0ccc92);
500         c = II(c, d, a, b, x[10], 15, 0xffeff47d);
501         b = II(b, c, d, a, x[ 1], 21, 0x85845dd1);
502         a = II(a, b, c, d, x[ 8], 6, 0x6fa87e4f);
503         d = II(d, a, b, c, x[15], 10, 0xfe2ce6e0);
504         c = II(c, d, a, b, x[ 6], 15, 0xa3014314);
505         b = II(b, c, d, a, x[13], 21, 0x4e0811a1);
506         a = II(a, b, c, d, x[ 4], 6, 0xf7537e82);
507         d = II(d, a, b, c, x[11], 10, 0xbd3af235);
508         c = II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);
509         b = II(b, c, d, a, x[ 9], 21, 0xeb86d391);
510
511         state[0] += a;
512         state[1] += b;
513         state[2] += c;
514         state[3] += d;
515     }
516 }
517
Popular Tags