View Javadoc

1   package org.apache.java.security;
2   
3   /* ====================================================================
4    * The Apache Software License, Version 1.1
5    *
6    * Copyright (c) 2001 The Apache Software Foundation.  All rights
7    * reserved.
8    *
9    * Redistribution and use in source and binary forms, with or without
10   * modification, are permitted provided that the following conditions
11   * are met:
12   *
13   * 1. Redistributions of source code must retain the above copyright
14   *    notice, this list of conditions and the following disclaimer.
15   *
16   * 2. Redistributions in binary form must reproduce the above copyright
17   *    notice, this list of conditions and the following disclaimer in
18   *    the documentation and/or other materials provided with the
19   *    distribution.
20   *
21   * 3. The end-user documentation included with the redistribution,
22   *    if any, must include the following acknowledgment:
23   *       "This product includes software developed by the
24   *        Apache Software Foundation (http://www.apache.org/)."
25   *    Alternately, this acknowledgment may appear in the software itself,
26   *    if and wherever such third-party acknowledgments normally appear.
27   *
28   * 4. The names "Apache" and "Apache Software Foundation" and 
29   *    "Apache Turbine" must not be used to endorse or promote products 
30   *    derived from this software without prior written permission. For 
31   *    written permission, please contact apache@apache.org.
32   *
33   * 5. Products derived from this software may not be called "Apache",
34   *    "Apache Turbine", nor may "Apache" appear in their name, without 
35   *    prior written permission of the Apache Software Foundation.
36   *
37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48   * SUCH DAMAGE.
49   * ====================================================================
50   *
51   * This software consists of voluntary contributions made by many
52   * individuals on behalf of the Apache Software Foundation.  For more
53   * information on the Apache Software Foundation, please see
54   * <http://www.apache.org/>.
55   */
56  
57  /***
58   * This class implements the Message Digest 5 algorithm (MD5) as
59   * defined in RFC-1321.
60   *
61   * <p><b>Note:</b> even if standard Java 1.1 APIs already provide a
62   * MD5 implementation, this class is used on those Java runtime
63   * environments (like Kaffe) where the package
64   * <code>java.security</code> is highly improbable to be found.
65   *
66   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
67   * @version $Id: MD5.java,v 1.2 2003/04/11 13:44:22 henning Exp $
68   * @deprecated Use the java.security package.
69   */
70  public final class MD5
71      extends MessageDigest
72  {
73      private long counter;
74      private int reminder;
75      private byte buffer[];
76      private int state[];
77      private int x[];
78  
79      /************************ MD5 Functions ***********************/
80  
81      // 16 * 4 bytes
82      static byte padding[] =
83      {
84          (byte) 0x80,
85          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
87          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
88          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
89      };
90  
91      /************************ Self Test ***********************/
92  
93      private static String[] messages =
94      {
95          "",
96          "a",
97          "abc",
98          "message digest",
99          "abcdefghijklmnopqrstuvwxyz",
100         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
101         "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
102     };
103 
104     private static String[] digests =
105     {
106         "d41d8cd98f00b204e9800998ecf8427e",
107         "0cc175b9c0f1b6a831c399e269772661",
108         "900150983cd24fb0d6963f7d28e17f72",
109         "f96b697d7cb7938d525a2f31aaf161d0",
110         "c3fcd3d76192e4007dfb496cca67e13b",
111         "d174ab98d277d9f5a5611c2c9f419d9f",
112         "57edf4a22be3c955ac49da2e2107b67a",
113     };
114 
115 
116     /***
117      * Creates the algorithm and reset its state.
118      */
119     public MD5()
120     {
121         super();
122     }
123 
124     /***
125      * Append another block of specified length to the message
126      * starting at the given offset.
127      *
128      * @param block A byte[].
129      * @param offset An int.
130      * @param length An int.
131      */
132     public void append(byte[] block,
133                        int offset,
134                        int length)
135     {
136         while (true)
137         {
138             if (length >= reminder)
139             {
140                 System.arraycopy(block, offset, buffer,
141                                  (int) (counter & 63L), reminder);
142                 transform(buffer);
143                 counter += reminder;
144                 offset += reminder;
145                 length -= reminder;
146                 reminder = 64;
147             }
148             else
149             {
150                 System.arraycopy(block, offset, buffer,
151                                  (int) (counter & 63L), length);
152                 counter += length;
153                 reminder -= length;
154                 break;
155             }
156         }
157     }
158 
159     /************************ Byte/Int utilities ***********************/
160 
161     /***
162      * Converts a 64-byte array into a 16-int array.
163      *
164      * @param in A byte[].
165      * @param out An int[].
166      */
167     private static void byte2int(byte[] in,
168                                  int[] out)
169     {
170         for (int inpos = 0, outpos = 0; outpos < 16; outpos++)
171         {
172             out[outpos] = ((((int) (in[inpos++] & 0xff))) |
173                            (((int) (in[inpos++] & 0xff)) << 8) |
174                            (((int) (in[inpos++] & 0xff)) << 16) |
175                            (((int) (in[inpos++] & 0xff)) << 24));
176         }
177     }
178 
179     /***
180      * Appends a message block with specified length starting from the
181      * given offset, and return its message digest.
182      *
183      * @param block A byte[].
184      * @param offset An int.
185      * @param length An int.
186      */
187     public byte[] digest(byte[] block,
188                          int offset,
189                          int length)
190     {
191         this.append(block, offset, length);
192 
193         byte[] bits = toBytes(counter << 3);
194         byte[] digest = new byte[16];
195 
196         if (reminder > 8)
197         {
198             append(padding, 0, reminder - 8);
199         }
200         else
201         {
202             append(padding, 0, 64 + (reminder - 8));
203         }
204 
205         append(bits, 0, 8);
206 
207         int2byte(state, digest);
208 
209         this.reset();
210         return digest;
211     }
212 
213     /*
214      * Method F.
215      *
216      * @param x An int.
217      * @param y An int.
218      * @param z An int.
219      * @return An int.
220      */
221     static private int F(int x,
222                          int y,
223                          int z)
224     {
225         return (z ^ (x & (y^z)));
226     }
227 
228     /*
229      * Method FF.
230      *
231      * @param a An int.
232      * @param b An int.
233      * @param c An int.
234      * @param d An int.
235      * @param x An int.
236      * @param s An int.
237      * @param ac An int.
238      * @return An int.
239      */
240     static private int FF(int a,
241                           int b,
242                           int c,
243                           int d,
244                           int x,
245                           int s,
246                           int ac)
247     {
248         a += x + ac + F(b,c,d);
249         a = (a << s | a >>> -s);
250         return a + b;
251     }
252 
253     /*
254      * Method G.
255      *
256      * @param x An int.
257      * @param y An int.
258      * @param z An int.
259      * @return An int.
260      */
261     static private int G(int x,
262                          int y,
263                          int z)
264     {
265         return (y ^ (z & (x^y)));
266     }
267 
268     /*
269      * Method GG.
270      *
271      * @param a An int.
272      * @param b An int.
273      * @param c An int.
274      * @param d An int.
275      * @param x An int.
276      * @param s An int.
277      * @param ac An int.
278      * @return An int.
279      */
280     static private int GG(int a,
281                           int b,
282                           int c,
283                           int d,
284                           int x,
285                           int s,
286                           int ac)
287     {
288         a += x + ac + G(b,c,d);
289         a = (a << s | a >>> -s);
290         return a + b;
291     }
292 
293     /*
294      * Method H.
295      *
296      * @param x An int.
297      * @param y An int.
298      * @param z An int.
299      * @return An int.
300      */
301     static private int H(int x,
302                          int y,
303                          int z)
304     {
305         return (x ^ y ^ z);
306     }
307 
308     /*
309      * Method HH.
310      *
311      * @param a An int.
312      * @param b An int.
313      * @param c An int.
314      * @param d An int.
315      * @param x An int.
316      * @param s An int.
317      * @param ac An int.
318      * @return An int.
319      */
320     static private int HH(int a,
321                           int b,
322                           int c,
323                           int d,
324                           int x,
325                           int s,
326                           int ac)
327     {
328         a += x + ac + H(b,c,d);
329         a = (a << s | a >>> -s);
330         return a + b;
331     }
332 
333     /*
334      * Method I.
335      *
336      * @param x An int.
337      * @param y An int.
338      * @param z An int.
339      * @return An int.
340      */
341     static private int I(int x,
342                          int y,
343                          int z)
344     {
345         return (y ^ (x | ~z));
346     }
347 
348     /*
349      * Method II.
350      *
351      * @param a An int.
352      * @param b An int.
353      * @param c An int.
354      * @param d An int.
355      * @param x An int.
356      * @param s An int.
357      * @param ac An int.
358      * @return An int.
359      */
360     static private int II(int a,
361                           int b,
362                           int c,
363                           int d,
364                           int x,
365                           int s,
366                           int ac)
367     {
368         a += x + ac + I(b,c,d);
369         a = (a << s | a >>> -s);
370         return a + b;
371     }
372 
373     /***
374      * Converts a 4-int array into a 16-byte array.
375      *
376      * @param in An int[].
377      * @param out A byte[].
378      */
379     private static void int2byte(int[] in,
380                                  byte[] out)
381     {
382         for (int inpos = 0, outpos = 0; inpos < 4; inpos++)
383         {
384             out[outpos++] = (byte) (in[inpos] & 0xff);
385             out[outpos++] = (byte) ((in[inpos] >>> 8) & 0xff);
386             out[outpos++] = (byte) ((in[inpos] >>> 16) & 0xff);
387             out[outpos++] = (byte) ((in[inpos] >>> 24) & 0xff);
388         }
389     }
390 
391     /*
392      * Main routine, for testing purposes only.
393      *
394      * @param ignored A String[] with the command line arguments.
395      */
396     public static final void main(String[] ignored)
397     {
398         MD5 md5 = new MD5();
399 
400         for (int i = 0; i < messages.length; i++)
401         {
402             String digest = org.apache.java.lang.Bytes.toString(
403                 md5.digest(messages[i].getBytes()));
404             System.out.println("Computed: " + digest);
405             System.out.println("Correct: " + digests[i]);
406             if (digest.equalsIgnoreCase(digests[i]))
407             {
408                 System.out.println("Test " + i + " passed.");
409             }
410             else
411             {
412                 System.out.println("Test " + i + " failed.");
413             }
414         }
415     }
416 
417     /***
418      * Resets the state of the class.  <b>Beware</b>: calling this
419      * method erases all data previously inserted.
420      */
421     public void reset()
422     {
423         buffer = new byte[64];
424         state = new int[4];
425         x = new int[16];
426 
427         state[0] = 0x67452301;
428         state[1] = 0xefcdab89;
429         state[2] = 0x98badcfe;
430         state[3] = 0x10325476;
431 
432         counter = 0;
433         reminder = 64;
434     }
435 
436     /***
437      * Converts a long to a 8-byte array using low order first.
438      *
439      * @param n A long.
440      * @return A byte[].
441      */
442     public static byte[] toBytes(long n)
443     {
444         byte[] b = new byte[8];
445 
446         b[0] = (byte) (n);
447         n >>>= 8;
448         b[1] = (byte) (n);
449         n >>>= 8;
450         b[2] = (byte) (n);
451         n >>>= 8;
452         b[3] = (byte) (n);
453         n >>>= 8;
454         b[4] = (byte) (n);
455         n >>>= 8;
456         b[5] = (byte) (n);
457         n >>>= 8;
458         b[6] = (byte) (n);
459         n >>>= 8;
460         b[7] = (byte) (n);
461 
462         return b;
463     }
464 
465     /*
466      * TODO: Document.
467      *
468      * @param buffer A byte[].
469      */
470     private void transform(byte[] buffer)
471     {
472         int a, b, c, d;
473 
474         byte2int(buffer, x);
475 
476         a = state[0];
477         b = state[1];
478         c = state[2];
479         d = state[3];
480 
481         a = FF(a, b, c, d, x[ 0],  7, 0xd76aa478);
482         d = FF(d, a, b, c, x[ 1], 12, 0xe8c7b756);
483         c = FF(c, d, a, b, x[ 2], 17, 0x242070db);
484         b = FF(b, c, d, a, x[ 3], 22, 0xc1bdceee);
485         a = FF(a, b, c, d, x[ 4],  7, 0xf57c0faf);
486         d = FF(d, a, b, c, x[ 5], 12, 0x4787c62a);
487         c = FF(c, d, a, b, x[ 6], 17, 0xa8304613);
488         b = FF(b, c, d, a, x[ 7], 22, 0xfd469501);
489         a = FF(a, b, c, d, x[ 8],  7, 0x698098d8);
490         d = FF(d, a, b, c, x[ 9], 12, 0x8b44f7af);
491         c = FF(c, d, a, b, x[10], 17, 0xffff5bb1);
492         b = FF(b, c, d, a, x[11], 22, 0x895cd7be);
493         a = FF(a, b, c, d, x[12],  7, 0x6b901122);
494         d = FF(d, a, b, c, x[13], 12, 0xfd987193);
495         c = FF(c, d, a, b, x[14], 17, 0xa679438e);
496         b = FF(b, c, d, a, x[15], 22, 0x49b40821);
497 
498         a = GG(a, b, c, d, x[ 1],  5, 0xf61e2562);
499         d = GG(d, a, b, c, x[ 6],  9, 0xc040b340);
500         c = GG(c, d, a, b, x[11], 14, 0x265e5a51);
501         b = GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);
502         a = GG(a, b, c, d, x[ 5],  5, 0xd62f105d);
503         d = GG(d, a, b, c, x[10],  9,  0x2441453);
504         c = GG(c, d, a, b, x[15], 14, 0xd8a1e681);
505         b = GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);
506         a = GG(a, b, c, d, x[ 9],  5, 0x21e1cde6);
507         d = GG(d, a, b, c, x[14],  9, 0xc33707d6);
508         c = GG(c, d, a, b, x[ 3], 14, 0xf4d50d87);
509         b = GG(b, c, d, a, x[ 8], 20, 0x455a14ed);
510         a = GG(a, b, c, d, x[13],  5, 0xa9e3e905);
511         d = GG(d, a, b, c, x[ 2],  9, 0xfcefa3f8);
512         c = GG(c, d, a, b, x[ 7], 14, 0x676f02d9);
513         b = GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);
514 
515         a = HH(a, b, c, d, x[ 5],  4, 0xfffa3942);
516         d = HH(d, a, b, c, x[ 8], 11, 0x8771f681);
517         c = HH(c, d, a, b, x[11], 16, 0x6d9d6122);
518         b = HH(b, c, d, a, x[14], 23, 0xfde5380c);
519         a = HH(a, b, c, d, x[ 1],  4, 0xa4beea44);
520         d = HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9);
521         c = HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60);
522         b = HH(b, c, d, a, x[10], 23, 0xbebfbc70);
523         a = HH(a, b, c, d, x[13],  4, 0x289b7ec6);
524         d = HH(d, a, b, c, x[ 0], 11, 0xeaa127fa);
525         c = HH(c, d, a, b, x[ 3], 16, 0xd4ef3085);
526         b = HH(b, c, d, a, x[ 6], 23,  0x4881d05);
527         a = HH(a, b, c, d, x[ 9],  4, 0xd9d4d039);
528         d = HH(d, a, b, c, x[12], 11, 0xe6db99e5);
529         c = HH(c, d, a, b, x[15], 16, 0x1fa27cf8);
530         b = HH(b, c, d, a, x[ 2], 23, 0xc4ac5665);
531 
532         a = II(a, b, c, d, x[ 0],  6, 0xf4292244);
533         d = II(d, a, b, c, x[ 7], 10, 0x432aff97);
534         c = II(c, d, a, b, x[14], 15, 0xab9423a7);
535         b = II(b, c, d, a, x[ 5], 21, 0xfc93a039);
536         a = II(a, b, c, d, x[12],  6, 0x655b59c3);
537         d = II(d, a, b, c, x[ 3], 10, 0x8f0ccc92);
538         c = II(c, d, a, b, x[10], 15, 0xffeff47d);
539         b = II(b, c, d, a, x[ 1], 21, 0x85845dd1);
540         a = II(a, b, c, d, x[ 8],  6, 0x6fa87e4f);
541         d = II(d, a, b, c, x[15], 10, 0xfe2ce6e0);
542         c = II(c, d, a, b, x[ 6], 15, 0xa3014314);
543         b = II(b, c, d, a, x[13], 21, 0x4e0811a1);
544         a = II(a, b, c, d, x[ 4],  6, 0xf7537e82);
545         d = II(d, a, b, c, x[11], 10, 0xbd3af235);
546         c = II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);
547         b = II(b, c, d, a, x[ 9], 21, 0xeb86d391);
548 
549         state[0] += a;
550         state[1] += b;
551         state[2] += c;
552         state[3] += d;
553     }
554 }