1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.fhw.cabaweb.tools;
24
25 /***
26 * Klasse um MD5 Hashes zu erstellen.
27 * Originalklasse von Jon Howell - mit kleinen Änderungen von Thomas Vogt
28 *
29 * This class computes MD5 hashes.
30 * Manually translated by Jon Howell <jonh@cs.dartmouth.edu>
31 * from some public domain C code (md5.c) included with the ssh-1.2.22 source.
32 * Tue Jan 19 15:55:50 EST 1999
33 * $Id: MD5.java,v 1.2 2004/11/11 08:44:25 cabaweb Exp $
34 *
35 * To compute the message digest of a chunk of bytes, create an
36 * MD5 object 'md5', call md5.update() as needed on buffers full
37 * of bytes, and then call md5.md5final(), which
38 * will fill a supplied 16-byte array with the digest.
39 *
40 * A main() method is included that hashes the data on System.in.
41 *
42 * It seems to run around 25-30 times slower (JDK1.1.6) than optimized C
43 * (gcc -O4, version 2.7.2.3). Measured on a Sun Ultra 5 (SPARC 270MHz).
44 *
45 * Comments from md5.c from ssh-1.2.22, the basis for this code:
46 *
47 * This code has been heavily hacked by Tatu Ylonen <ylo@cs.hut.fi> to
48 * make it compile on machines like Cray that don't have a 32 bit integer
49 * type.
50 *
51 * This code implements the MD5 message-digest algorithm.
52 * The algorithm is due to Ron Rivest. This code was
53 * written by Colin Plumb in 1993, no copyright is claimed.
54 * This code is in the public domain; do with it what you wish.
55 *
56 * Equivalent code is available from RSA Data Security, Inc.
57 * This code has been tested against that, and is equivalent,
58 * except that you don't need to include two pages of legalese
59 * with every copy.
60 *
61 * To compute the message digest of a chunk of bytes, declare an
62 * MD5Context structure, pass it to MD5Init, call MD5Update as
63 * needed on buffers full of bytes, and then call MD5Final, which
64 * will fill a supplied 16-byte array with the digest.
65 *
66 * @author Jon Howell <jonh@cs.dartmouth.edu>
67 * @version 19.01.1999 21:30:11 - Changes 10.03.2004
68 */
69 public class MD5
70 {
71 /***
72 * These were originally unsigned ints.
73 * This Java code makes an effort to avoid sign traps.
74 * buf[] is where the hash accumulates.
75 */
76 private int[] buf;
77 /***
78 * This is the count of bits hashed so far.
79 */
80 private long bits;
81 /***
82 * This is a buffer where we stash bytes until we have
83 * enough (64) to perform a transform operation.
84 */
85 private byte[] in;
86 /***
87 * inint[] used and discarded inside transform(),
88 * but why allocate it over and over?
89 * (In the C version this is allocated on the stack.)
90 */
91 private int[] inint;
92
93 /***
94 * Konstruktor
95 */
96 public MD5()
97 {
98 buf = new int[4];
99
100 buf[0] = 0x67452301;
101 buf[1] = 0xefcdab89;
102 buf[2] = 0x98badcfe;
103 buf[3] = 0x10325476;
104
105
106 bits = 0L;
107
108 in = new byte[64];
109 inint = new int[16];
110 }
111
112 /***
113 * No Comment
114 */
115 public void update(final byte[] newbuf)
116 {
117 update(newbuf, 0, newbuf.length);
118 }
119
120 /***
121 * No Comment
122 */
123 public void update(final byte[] newbuf, final int length)
124 {
125 update(newbuf, 0, length);
126 }
127
128 /***
129 * No Comment
130 */
131 public void update(final byte[] newbuf, int bufstart, final int buflen)
132 {
133 int t;
134 int len = buflen;
135
136
137
138 t = (int) bits;
139
140
141
142
143
144
145 bits += (long) (len << 3);
146
147 t = (t >>> 3) & 0x3f;
148
149
150
151
152 if (t != 0)
153 {
154 int p = t;
155 t = 64 - t;
156 if (len < t)
157 {
158 System.arraycopy(newbuf, bufstart, in, p, len);
159 return;
160 }
161 System.arraycopy(newbuf, bufstart, in, p, t);
162 transform();
163 bufstart += t;
164 len -= t;
165 }
166
167
168 while (len >= 64)
169 {
170 System.arraycopy(newbuf, bufstart, in, 0, 64);
171 transform();
172 bufstart += 64;
173 len -= 64;
174 }
175
176
177
178 System.arraycopy(newbuf, bufstart, in, 0, len);
179 }
180
181 /***
182 * Final wrapup - pad to 64-byte boundary with the bit pattern
183 * 1 0* (64-bit count of bits processed, MSB-first)
184 */
185 public void md5final(final byte[] digest)
186 {
187
188 int count;
189 int p;
190
191
192
193 count = (int) ((bits >>> 3) & 0x3F);
194
195
196
197 p = count;
198 in[p++] = (byte) 0x80;
199
200
201 count = 64 - 1 - count;
202
203
204 if (count < 8)
205 {
206
207 zeroByteArray(in, p, count);
208 transform();
209
210
211 zeroByteArray(in, 0, 56);
212 }
213 else
214 {
215
216 zeroByteArray(in, p, count - 8);
217 }
218
219
220
221
222
223 int lowbits = (int) bits;
224 int highbits = (int) (bits >>> 32);
225 PUT_32BIT_LSB_FIRST(in, 56, lowbits);
226 PUT_32BIT_LSB_FIRST(in, 60, highbits);
227
228 transform();
229 PUT_32BIT_LSB_FIRST(digest, 0, buf[0]);
230 PUT_32BIT_LSB_FIRST(digest, 4, buf[1]);
231 PUT_32BIT_LSB_FIRST(digest, 8, buf[2]);
232 PUT_32BIT_LSB_FIRST(digest, 12, buf[3]);
233
234
235
236
237
238
239 zeroByteArray(in);
240 zeroIntArray(buf);
241 bits = 0;
242 zeroIntArray(inint);
243 }
244
245 /***
246 * No Comment
247 */
248 public String dumpBytes(final byte[] bytes)
249 {
250 int i;
251 StringBuffer sb = new StringBuffer();
252 for (i = 0; i < bytes.length; i++)
253 {
254 if (i % 32 == 0 && i != 0)
255 {
256 sb.append("\n");
257 }
258 String s = Integer.toHexString(bytes[i]);
259 if (s.length() < 2)
260 {
261 s = "0" + s;
262 }
263 if (s.length() > 2)
264 {
265 s = s.substring(s.length() - 2);
266 }
267 sb.append(s);
268 }
269 return sb.toString();
270 }
271
272
273
274
275
276
277
278
279 /***
280 * No Comment
281 */
282 private void zeroByteArray(final byte[] a)
283 {
284 zeroByteArray(a, 0, a.length);
285 }
286
287 /***
288 * No Comment
289 */
290 private void zeroByteArray(final byte[] a, final int start, final int length)
291 {
292 setByteArray(a, (byte) 0, start, length);
293 }
294
295 /***
296 * No Comment
297 */
298 private void setByteArray(final byte[] a, final byte val, final int start, final int length)
299 {
300 int i;
301 int end = start + length;
302 for (i = start; i < end; i++)
303 {
304 a[i] = val;
305 }
306 }
307
308 /***
309 * No Comment
310 */
311 private void zeroIntArray(final int[] a)
312 {
313 zeroIntArray(a, 0, a.length);
314 }
315
316 /***
317 * No Comment
318 */
319 private void zeroIntArray(final int[] a, final int start, final int length)
320 {
321 setIntArray(a, (int) 0, start, length);
322 }
323
324 /***
325 * No Comment
326 */
327 private void setIntArray(final int[] a, final int val, final int start, final int length)
328 {
329 int i;
330 int end = start + length;
331 for (i = start; i < end; i++)
332 {
333 a[i] = val;
334 }
335 }
336
337
338
339
340
341
342
343
344
345 /***
346 * No Comment
347 */
348 private abstract class Fcore
349 {
350 abstract int f(final int x, final int y, final int z);
351 }
352
353 /***
354 * No Comment
355 */
356 private Fcore F1 = new Fcore()
357 {
358 int f(final int x, final int y, final int z)
359 {
360 return (z ^ (x & (y ^ z)));
361 }
362 };
363
364 /***
365 * No Comment
366 */
367 private Fcore F2 = new Fcore()
368 {
369 int f(final int x, final int y, final int z)
370 {
371 return (y ^ (z & (x ^ y)));
372 }
373 };
374
375 /***
376 * No Comment
377 */
378 private Fcore F3 = new Fcore()
379 {
380 int f(final int x, final int y, final int z)
381 {
382 return (x ^ y ^ z);
383 }
384 };
385
386 /***
387 * No Comment
388 */
389 private Fcore F4 = new Fcore()
390 {
391 int f(final int x, final int y, final int z)
392 {
393 return (y ^ (x | ~z));
394 }
395 };
396
397 /***
398 * No Comment
399 */
400 private int MD5STEP(final Fcore f, int w, final int x, final int y, final int z, final int data, final int s)
401 {
402 w += f.f(x, y, z) + data;
403 w = w << s | w >>> (32 - s);
404 w += x;
405 return w;
406 }
407
408 /***
409 * No Comment
410 */
411 private void transform()
412 {
413
414 int i;
415 int[] inint = new int[16];
416
417 for (i = 0; i < 16; i++)
418 {
419 inint[i] = GET_32BIT_LSB_FIRST(in, 4 * i);
420 }
421
422 int a, b, c, d;
423 a = buf[0];
424 b = buf[1];
425 c = buf[2];
426 d = buf[3];
427
428 a = MD5STEP(F1, a, b, c, d, inint[0] + 0xd76aa478, 7);
429 d = MD5STEP(F1, d, a, b, c, inint[1] + 0xe8c7b756, 12);
430 c = MD5STEP(F1, c, d, a, b, inint[2] + 0x242070db, 17);
431 b = MD5STEP(F1, b, c, d, a, inint[3] + 0xc1bdceee, 22);
432 a = MD5STEP(F1, a, b, c, d, inint[4] + 0xf57c0faf, 7);
433 d = MD5STEP(F1, d, a, b, c, inint[5] + 0x4787c62a, 12);
434 c = MD5STEP(F1, c, d, a, b, inint[6] + 0xa8304613, 17);
435 b = MD5STEP(F1, b, c, d, a, inint[7] + 0xfd469501, 22);
436 a = MD5STEP(F1, a, b, c, d, inint[8] + 0x698098d8, 7);
437 d = MD5STEP(F1, d, a, b, c, inint[9] + 0x8b44f7af, 12);
438 c = MD5STEP(F1, c, d, a, b, inint[10] + 0xffff5bb1, 17);
439 b = MD5STEP(F1, b, c, d, a, inint[11] + 0x895cd7be, 22);
440 a = MD5STEP(F1, a, b, c, d, inint[12] + 0x6b901122, 7);
441 d = MD5STEP(F1, d, a, b, c, inint[13] + 0xfd987193, 12);
442 c = MD5STEP(F1, c, d, a, b, inint[14] + 0xa679438e, 17);
443 b = MD5STEP(F1, b, c, d, a, inint[15] + 0x49b40821, 22);
444
445 a = MD5STEP(F2, a, b, c, d, inint[1] + 0xf61e2562, 5);
446 d = MD5STEP(F2, d, a, b, c, inint[6] + 0xc040b340, 9);
447 c = MD5STEP(F2, c, d, a, b, inint[11] + 0x265e5a51, 14);
448 b = MD5STEP(F2, b, c, d, a, inint[0] + 0xe9b6c7aa, 20);
449 a = MD5STEP(F2, a, b, c, d, inint[5] + 0xd62f105d, 5);
450 d = MD5STEP(F2, d, a, b, c, inint[10] + 0x02441453, 9);
451 c = MD5STEP(F2, c, d, a, b, inint[15] + 0xd8a1e681, 14);
452 b = MD5STEP(F2, b, c, d, a, inint[4] + 0xe7d3fbc8, 20);
453 a = MD5STEP(F2, a, b, c, d, inint[9] + 0x21e1cde6, 5);
454 d = MD5STEP(F2, d, a, b, c, inint[14] + 0xc33707d6, 9);
455 c = MD5STEP(F2, c, d, a, b, inint[3] + 0xf4d50d87, 14);
456 b = MD5STEP(F2, b, c, d, a, inint[8] + 0x455a14ed, 20);
457 a = MD5STEP(F2, a, b, c, d, inint[13] + 0xa9e3e905, 5);
458 d = MD5STEP(F2, d, a, b, c, inint[2] + 0xfcefa3f8, 9);
459 c = MD5STEP(F2, c, d, a, b, inint[7] + 0x676f02d9, 14);
460 b = MD5STEP(F2, b, c, d, a, inint[12] + 0x8d2a4c8a, 20);
461
462 a = MD5STEP(F3, a, b, c, d, inint[5] + 0xfffa3942, 4);
463 d = MD5STEP(F3, d, a, b, c, inint[8] + 0x8771f681, 11);
464 c = MD5STEP(F3, c, d, a, b, inint[11] + 0x6d9d6122, 16);
465 b = MD5STEP(F3, b, c, d, a, inint[14] + 0xfde5380c, 23);
466 a = MD5STEP(F3, a, b, c, d, inint[1] + 0xa4beea44, 4);
467 d = MD5STEP(F3, d, a, b, c, inint[4] + 0x4bdecfa9, 11);
468 c = MD5STEP(F3, c, d, a, b, inint[7] + 0xf6bb4b60, 16);
469 b = MD5STEP(F3, b, c, d, a, inint[10] + 0xbebfbc70, 23);
470 a = MD5STEP(F3, a, b, c, d, inint[13] + 0x289b7ec6, 4);
471 d = MD5STEP(F3, d, a, b, c, inint[0] + 0xeaa127fa, 11);
472 c = MD5STEP(F3, c, d, a, b, inint[3] + 0xd4ef3085, 16);
473 b = MD5STEP(F3, b, c, d, a, inint[6] + 0x04881d05, 23);
474 a = MD5STEP(F3, a, b, c, d, inint[9] + 0xd9d4d039, 4);
475 d = MD5STEP(F3, d, a, b, c, inint[12] + 0xe6db99e5, 11);
476 c = MD5STEP(F3, c, d, a, b, inint[15] + 0x1fa27cf8, 16);
477 b = MD5STEP(F3, b, c, d, a, inint[2] + 0xc4ac5665, 23);
478
479 a = MD5STEP(F4, a, b, c, d, inint[0] + 0xf4292244, 6);
480 d = MD5STEP(F4, d, a, b, c, inint[7] + 0x432aff97, 10);
481 c = MD5STEP(F4, c, d, a, b, inint[14] + 0xab9423a7, 15);
482 b = MD5STEP(F4, b, c, d, a, inint[5] + 0xfc93a039, 21);
483 a = MD5STEP(F4, a, b, c, d, inint[12] + 0x655b59c3, 6);
484 d = MD5STEP(F4, d, a, b, c, inint[3] + 0x8f0ccc92, 10);
485 c = MD5STEP(F4, c, d, a, b, inint[10] + 0xffeff47d, 15);
486 b = MD5STEP(F4, b, c, d, a, inint[1] + 0x85845dd1, 21);
487 a = MD5STEP(F4, a, b, c, d, inint[8] + 0x6fa87e4f, 6);
488 d = MD5STEP(F4, d, a, b, c, inint[15] + 0xfe2ce6e0, 10);
489 c = MD5STEP(F4, c, d, a, b, inint[6] + 0xa3014314, 15);
490 b = MD5STEP(F4, b, c, d, a, inint[13] + 0x4e0811a1, 21);
491 a = MD5STEP(F4, a, b, c, d, inint[4] + 0xf7537e82, 6);
492 d = MD5STEP(F4, d, a, b, c, inint[11] + 0xbd3af235, 10);
493 c = MD5STEP(F4, c, d, a, b, inint[2] + 0x2ad7d2bb, 15);
494 b = MD5STEP(F4, b, c, d, a, inint[9] + 0xeb86d391, 21);
495
496 buf[0] += a;
497 buf[1] += b;
498 buf[2] += c;
499 buf[3] += d;
500 }
501
502 /***
503 * No Comment
504 */
505 private int GET_32BIT_LSB_FIRST(final byte[] b, final int off)
506 {
507 return ((int) (b[off + 0] & 0xff)) | ((int) (b[off + 1] & 0xff) << 8) | ((int) (b[off + 2] & 0xff) << 16) | ((int) (b[off + 3] & 0xff) << 24);
508 }
509
510 /***
511 * No Comment
512 */
513 private void PUT_32BIT_LSB_FIRST(final byte[] b, final int off, final int value)
514 {
515 b[off + 0] = (byte) (value & 0xff);
516 b[off + 1] = (byte) ((value >> 8) & 0xff);
517 b[off + 2] = (byte) ((value >> 16) & 0xff);
518 b[off + 3] = (byte) ((value >> 24) & 0xff);
519 }
520
521 /***
522 * These are debug routines I was using while trying to
523 * get this code to generate the same hashes as the C version.
524 * (IIRC, all the errors were due to the absence of unsigned
525 * ints in Java.)
526 *
527 * @deprecated
528 */
529 private void debugStatus(String m)
530 {
531 System.out.println(m + ":");
532 System.out.println("in: " + dumpBytes(in));
533 System.out.println("bits: " + bits);
534 System.out.println("buf: " + Integer.toHexString(buf[0]) + " " + Integer.toHexString(buf[1]) + " " + Integer.toHexString(buf[2]) + " " + Integer.toHexString(buf[3]));
535 }
536 }