API Overview API Index Package Overview Direct link to this page
JDK 1.6
  java.security. MessageDigest View Javadoc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557

/*
 * @(#)MessageDigest.java	1.81 06/04/21
 *
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package java.security;

import java.util.*;
import java.lang.*;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.InputStream;
import java.io.ByteArrayInputStream;

import java.nio.ByteBuffer;

/**
 * This MessageDigest class provides applications the functionality of a
 * message digest algorithm, such as MD5 or SHA.
 * Message digests are secure one-way hash functions that take arbitrary-sized
 * data and output a fixed-length hash value.
 *
 * <p>A MessageDigest object starts out initialized. The data is 
 * processed through it using the {@link #update(byte) update}
 * methods. At any point {@link #reset() reset} can be called
 * to reset the digest. Once all the data to be updated has been
 * updated, one of the {@link #digest() digest} methods should 
 * be called to complete the hash computation.
 *
 * <p>The <code>digest</code> method can be called once for a given number 
 * of updates. After <code>digest</code> has been called, the MessageDigest
 * object is reset to its initialized state.
 *
 * <p>Implementations are free to implement the Cloneable interface.
 * Client applications can test cloneability by attempting cloning
 * and catching the CloneNotSupportedException: <p>    
 *
* <pre>
* MessageDigest md = MessageDigest.getInstance("SHA");
*
* try {
*     md.update(toChapter1);
*     MessageDigest tc1 = md.clone();
*     byte[] toChapter1Digest = tc1.digest();
*     md.update(toChapter2);
*     ...etc.
* } catch (CloneNotSupportedException cnse) {
*     throw new DigestException("couldn't make digest of partial content");
* }
* </pre>
 *
 * <p>Note that if a given implementation is not cloneable, it is
 * still possible to compute intermediate digests by instantiating
 * several instances, if the number of digests is known in advance.
 *
 * <p>Note that this class is abstract and extends from
 * <code>MessageDigestSpi</code> for historical reasons.
 * Application developers should only take notice of the methods defined in
 * this <code>MessageDigest</code> class; all the methods in
 * the superclass are intended for cryptographic service providers who wish to
 * supply their own implementations of message digest algorithms.
 *
 * @author Benjamin Renaud 
 *
 * @version 1.81, 04/21/06
 *
 * @see DigestInputStream
 * @see DigestOutputStream
 */

public abstract class MessageDigest extends MessageDigestSpi {

    private String algorithm;

    // The state of this digest
    private static final int INITIAL = 0;
    private static final int IN_PROGRESS = 1;
    private int state = INITIAL;

    // The provider
    private Provider provider;

    /**
     * Creates a message digest with the specified algorithm name.
     * 
     * @param algorithm the standard name of the digest algorithm. 
     * See Appendix A in the <a href=
     * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
     * Java Cryptography Architecture API Specification &amp; Reference </a> 
     * for information about standard algorithm names.
     */
    protected MessageDigest(String algorithm) {
	this.algorithm = algorithm;
    }

    /**
     * Returns a MessageDigest object that implements the specified digest
     * algorithm.
     *
     * <p> This method traverses the list of registered security Providers,
     * starting with the most preferred Provider.
     * A new MessageDigest object encapsulating the
     * MessageDigestSpi implementation from the first
     * Provider that supports the specified algorithm is returned.
     *
     * <p> Note that the list of registered providers may be retrieved via
     * the {@link Security#getProviders() Security.getProviders()} method.
     *
     * @param algorithm the name of the algorithm requested. 
     * See Appendix A in the <a href=
     * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
     * Java Cryptography Architecture API Specification &amp; Reference </a> 
     * for information about standard algorithm names.
     *
     * @return a Message Digest object that implements the specified algorithm.
     *
     * @exception NoSuchAlgorithmException if no Provider supports a
     *		MessageDigestSpi implementation for the
     *		specified algorithm.
     *
     * @see Provider
     */
    public static MessageDigest getInstance(String algorithm) 
    throws NoSuchAlgorithmException { 
	try {
	    Object[] objs = Security.getImpl(algorithm, "MessageDigest",
					     (String)null);
	    if (objs[0] instanceof MessageDigest) {
		MessageDigest md = (MessageDigest)objs[0];
		md.provider = (Provider)objs[1];
		return md;
	    } else {
		MessageDigest delegate =
		    new Delegate((MessageDigestSpi)objs[0], algorithm);
		delegate.provider = (Provider)objs[1];
		return delegate;
	    }
	} catch(NoSuchProviderException e) {
	    throw new NoSuchAlgorithmException(algorithm + " not found");
	}
    }

    /**
     * Returns a MessageDigest object that implements the specified digest
     * algorithm.
     *
     * <p> A new MessageDigest object encapsulating the
     * MessageDigestSpi implementation from the specified provider
     * is returned.  The specified provider must be registered
     * in the security provider list.
     *
     * <p> Note that the list of registered providers may be retrieved via
     * the {@link Security#getProviders() Security.getProviders()} method.
     *
     * @param algorithm the name of the algorithm requested. 
     * See Appendix A in the <a href=
     * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
     * Java Cryptography Architecture API Specification &amp; Reference </a> 
     * for information about standard algorithm names.
     *
     * @param provider the name of the provider.
     *
     * @return a MessageDigest object that implements the specified algorithm.
     *
     * @exception NoSuchAlgorithmException if a MessageDigestSpi
     *		implementation for the specified algorithm is not
     *		available from the specified provider.
     *
     * @exception NoSuchProviderException if the specified provider is not
     *		registered in the security provider list.
     *
     * @exception IllegalArgumentException if the provider name is null
     *		or empty.
     *
     * @see Provider 
     */
    public static MessageDigest getInstance(String algorithm, String provider)
	throws NoSuchAlgorithmException, NoSuchProviderException
    {
	if (provider == null || provider.length() == 0)
	    throw new IllegalArgumentException("missing provider");
	Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
	if (objs[0] instanceof MessageDigest) {
	    MessageDigest md = (MessageDigest)objs[0];
	    md.provider = (Provider)objs[1];
	    return md;
	} else {
	    MessageDigest delegate =
		new Delegate((MessageDigestSpi)objs[0], algorithm);
	    delegate.provider = (Provider)objs[1];
	    return delegate;
	}
    }

    /**
     * Returns a MessageDigest object that implements the specified digest
     * algorithm.
     *
     * <p> A new MessageDigest object encapsulating the
     * MessageDigestSpi implementation from the specified Provider
     * object is returned.  Note that the specified Provider object
     * does not have to be registered in the provider list.
     *
     * @param algorithm the name of the algorithm requested. 
     * See Appendix A in the <a href=
     * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
     * Java Cryptography Architecture API Specification &amp; Reference </a> 
     * for information about standard algorithm names.
     *
     * @param provider the provider.
     *
     * @return a MessageDigest object that implements the specified algorithm.
     *
     * @exception NoSuchAlgorithmException if a MessageDigestSpi
     *		implementation for the specified algorithm is not available
     *		from the specified Provider object.
     *
     * @exception IllegalArgumentException if the specified provider is null.
     *
     * @see Provider
     *
     * @since 1.4
     */
    public static MessageDigest getInstance(String algorithm,
					    Provider provider)
	throws NoSuchAlgorithmException
    {
	if (provider == null)
	    throw new IllegalArgumentException("missing provider");
	Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
	if (objs[0] instanceof MessageDigest) {
	    MessageDigest md = (MessageDigest)objs[0];
	    md.provider = (Provider)objs[1];
	    return md;
	} else {
	    MessageDigest delegate =
		new Delegate((MessageDigestSpi)objs[0], algorithm);
	    delegate.provider = (Provider)objs[1];
	    return delegate;
	}
    }

    /** 
     * Returns the provider of this message digest object.
     * 
     * @return the provider of this message digest object
     */
    public final Provider getProvider() {
	return this.provider;
    }

    /**
     * Updates the digest using the specified byte.    
     * 
     * @param input the byte with which to update the digest.
     */
    public void update(byte input) {
	engineUpdate(input);
	state = IN_PROGRESS;
    }

    /**
     * Updates the digest using the specified array of bytes, starting
     * at the specified offset.
     * 
     * @param input the array of bytes.
     *
     * @param offset the offset to start from in the array of bytes.
     *
     * @param len the number of bytes to use, starting at 
     * <code>offset</code>.  
     */
    public void update(byte[] input, int offset, int len) {
	if (input == null) {
	    throw new IllegalArgumentException("No input buffer given");
	}
	if (input.length - offset < len) {
	    throw new IllegalArgumentException("Input buffer too short");
	}
	engineUpdate(input, offset, len);
	state = IN_PROGRESS;
    }

    /**
     * Updates the digest using the specified array of bytes.
     * 
     * @param input the array of bytes.
     */
    public void update(byte[] input) {
	engineUpdate(input, 0, input.length);
	state = IN_PROGRESS;
    }

    /**
     * Update the digest using the specified ByteBuffer. The digest is
     * updated using the <code>input.remaining()</code> bytes starting
     * at <code>input.position()</code>.
     * Upon return, the buffer's position will be equal to its limit;
     * its limit will not have changed.
     *
     * @param input the ByteBuffer
     * @since 1.5
     */
    public final void update(ByteBuffer input) {
	if (input == null) {
	    throw new NullPointerException();
	}
	engineUpdate(input);
	state = IN_PROGRESS;
    }

    /**
     * Completes the hash computation by performing final operations
     * such as padding. The digest is reset after this call is made.
     *
     * @return the array of bytes for the resulting hash value.  
     */
    public byte[] digest() {
	/* Resetting is the responsibility of implementors. */
	byte[] result = engineDigest();
	state = INITIAL;
	return result;
    }

    /**
     * Completes the hash computation by performing final operations
     * such as padding. The digest is reset after this call is made.
     *
     * @param buf output buffer for the computed digest
     *
     * @param offset offset into the output buffer to begin storing the digest
     *
     * @param len number of bytes within buf allotted for the digest
     *
     * @return the number of bytes placed into <code>buf</code>
     * 
     * @exception DigestException if an error occurs.
     */
    public int digest(byte[] buf, int offset, int len) throws DigestException {
	if (buf == null) {
	    throw new IllegalArgumentException("No output buffer given");
	}
	if (buf.length - offset < len) {
	    throw new IllegalArgumentException
		("Output buffer too small for specified offset and length");
	}
	int numBytes = engineDigest(buf, offset, len);
	state = INITIAL;
	return numBytes;
    }

    /**
     * Performs a final update on the digest using the specified array 
     * of bytes, then completes the digest computation. That is, this
     * method first calls {@link #update(byte[]) update(input)},
     * passing the <i>input</i> array to the <code>update</code> method,
     * then calls {@link #digest() digest()}.
     *
     * @param input the input to be updated before the digest is
     * completed.
     *
     * @return the array of bytes for the resulting hash value.  
     */
    public byte[] digest(byte[] input) {
	update(input);
	return digest();
    }

    /**
     * Returns a string representation of this message digest object.  
     */
    public String toString() {
	ByteArrayOutputStream baos = new ByteArrayOutputStream();
	PrintStream p = new PrintStream(baos);
	p.print(algorithm+" Message Digest from "+provider.getName()+", ");
	switch (state) {
	case INITIAL:
	    p.print("<initialized>");
	    break;
	case IN_PROGRESS:
	    p.print("<in progress>");
	    break;
	}
	p.println();
	return (baos.toString());
    }

    /**
     * Compares two digests for equality. Does a simple byte compare.
     * 
     * @param digesta one of the digests to compare.
     * 
     * @param digestb the other digest to compare.    
     *
     * @return true if the digests are equal, false otherwise.
     */
    public static boolean isEqual(byte digesta[], byte digestb[]) {
	if (digesta.length != digestb.length)
	    return false;

	for (int i = 0; i < digesta.length; i++) {
	    if (digesta[i] != digestb[i]) {
		return false;
	    }
	}
	return true;
    }

    /**
     * Resets the digest for further use.
     */
    public void reset() {
	engineReset();
	state = INITIAL;
    }

    /** 
     * Returns a string that identifies the algorithm, independent of
     * implementation details. The name should be a standard
     * Java Security name (such as "SHA", "MD5", and so on). 
     * See Appendix A in the <a href=
     * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
     * Java Cryptography Architecture API Specification &amp; Reference </a> 
     * for information about standard algorithm names.
     *
     * @return the name of the algorithm
     */
    public final String getAlgorithm() {
	return this.algorithm;
    }

    /** 
     * Returns the length of the digest in bytes, or 0 if this operation is
     * not supported by the provider and the implementation is not cloneable.
     *
     * @return the digest length in bytes, or 0 if this operation is not
     * supported by the provider and the implementation is not cloneable.
     * 
     * @since 1.2
     */
    public final int getDigestLength() {
	int digestLen = engineGetDigestLength();
	if (digestLen == 0) {
	    try {
		MessageDigest md = (MessageDigest)clone();
		byte[] digest = md.digest();
		return digest.length;
	    } catch (CloneNotSupportedException e) {
		return digestLen;
	    }
	}
	return digestLen;
    }

    /**    
     * Returns a clone if the implementation is cloneable.    
     * 
     * @return a clone if the implementation is cloneable.
     *
     * @exception CloneNotSupportedException if this is called on an
     * implementation that does not support <code>Cloneable</code>.
     */
    public Object clone() throws CloneNotSupportedException {
	if (this instanceof Cloneable) {
	    return super.clone();
	} else {
	    throw new CloneNotSupportedException();
	}
    }




    /*
     * The following class allows providers to extend from MessageDigestSpi
     * rather than from MessageDigest. It represents a MessageDigest with an
     * encapsulated, provider-supplied SPI object (of type MessageDigestSpi).
     * If the provider implementation is an instance of MessageDigestSpi,
     * the getInstance() methods above return an instance of this class, with
     * the SPI object encapsulated.
     *
     * Note: All SPI methods from the original MessageDigest class have been
     * moved up the hierarchy into a new class (MessageDigestSpi), which has
     * been interposed in the hierarchy between the API (MessageDigest)
     * and its original parent (Object).
     */

    static class Delegate extends MessageDigest {

	// The provider implementation (delegate)
	private MessageDigestSpi digestSpi;

	// constructor
	public Delegate(MessageDigestSpi digestSpi, String algorithm) {
	    super(algorithm);
	    this.digestSpi = digestSpi;
	}

	/**
	 * Returns a clone if the delegate is cloneable.    
	 * 
	 * @return a clone if the delegate is cloneable.
	 *
	 * @exception CloneNotSupportedException if this is called on a
	 * delegate that does not support <code>Cloneable</code>.
	 */
	public Object clone() throws CloneNotSupportedException {
	    if (digestSpi instanceof Cloneable) {
		MessageDigestSpi digestSpiClone =
		    (MessageDigestSpi)digestSpi.clone();	
		// Because 'algorithm', 'provider', and 'state' are private
		// members of our supertype, we must perform a cast to
		// access them.
		MessageDigest that =
		    new Delegate(digestSpiClone,
				 ((MessageDigest)this).algorithm);
		that.provider = ((MessageDigest)this).provider;
		that.state = ((MessageDigest)this).state;
		return that;
	    } else {
		throw new CloneNotSupportedException();
	    }
	}

	protected int engineGetDigestLength() {
	    return digestSpi.engineGetDigestLength();
	}

	protected void engineUpdate(byte input) {
	    digestSpi.engineUpdate(input);
	}

	protected void engineUpdate(byte[] input, int offset, int len) {
	    digestSpi.engineUpdate(input, offset, len);
	}

	protected void engineUpdate(ByteBuffer input) {
	    digestSpi.engineUpdate(input);
	}

	protected byte[] engineDigest() {
	    return digestSpi.engineDigest();
	}

	protected int engineDigest(byte[] buf, int offset, int len)
	    throws DigestException {
		return digestSpi.engineDigest(buf, offset, len);
	}

	protected void engineReset() {
	    digestSpi.engineReset();
	}
    }
}

Generated By: JavaOnTracks Doclet 0.1.4     ©Thibaut Colar