Source code: org/apache/java/security/MD5.java
1 package org.apache.java.security;
2
3 /*
4 * Copyright 2001-2005 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 264148 2005-08-29 14:21:04Z henning $
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[] messages =
56 {
57 "",
58 "a",
59 "abc",
60 "message digest",
61 "abcdefghijklmnopqrstuvwxyz",
62 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
63 "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
64 };
65
66 private static String[] 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[] ignored)
359 {
360 MD5 md5 = new MD5();
361
362 for (int i = 0; i < messages.length; i++)
363 {
364 String 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 }