Source Code Cross Referenced for MessageDigest.java in  » 6.0-JDK-Core » security » java » security » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » security » java.security 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package java.security;
027
028        import java.util.*;
029        import java.lang.*;
030        import java.io.IOException;
031        import java.io.ByteArrayOutputStream;
032        import java.io.PrintStream;
033        import java.io.InputStream;
034        import java.io.ByteArrayInputStream;
035
036        import java.nio.ByteBuffer;
037
038        /**
039         * This MessageDigest class provides applications the functionality of a
040         * message digest algorithm, such as MD5 or SHA.
041         * Message digests are secure one-way hash functions that take arbitrary-sized
042         * data and output a fixed-length hash value.
043         *
044         * <p>A MessageDigest object starts out initialized. The data is 
045         * processed through it using the {@link #update(byte) update}
046         * methods. At any point {@link #reset() reset} can be called
047         * to reset the digest. Once all the data to be updated has been
048         * updated, one of the {@link #digest() digest} methods should 
049         * be called to complete the hash computation.
050         *
051         * <p>The <code>digest</code> method can be called once for a given number 
052         * of updates. After <code>digest</code> has been called, the MessageDigest
053         * object is reset to its initialized state.
054         *
055         * <p>Implementations are free to implement the Cloneable interface.
056         * Client applications can test cloneability by attempting cloning
057         * and catching the CloneNotSupportedException: <p>    
058         *
059         * <pre>
060         * MessageDigest md = MessageDigest.getInstance("SHA");
061         *
062         * try {
063         *     md.update(toChapter1);
064         *     MessageDigest tc1 = md.clone();
065         *     byte[] toChapter1Digest = tc1.digest();
066         *     md.update(toChapter2);
067         *     ...etc.
068         * } catch (CloneNotSupportedException cnse) {
069         *     throw new DigestException("couldn't make digest of partial content");
070         * }
071         * </pre>
072         *
073         * <p>Note that if a given implementation is not cloneable, it is
074         * still possible to compute intermediate digests by instantiating
075         * several instances, if the number of digests is known in advance.
076         *
077         * <p>Note that this class is abstract and extends from
078         * <code>MessageDigestSpi</code> for historical reasons.
079         * Application developers should only take notice of the methods defined in
080         * this <code>MessageDigest</code> class; all the methods in
081         * the superclass are intended for cryptographic service providers who wish to
082         * supply their own implementations of message digest algorithms.
083         *
084         * @author Benjamin Renaud 
085         *
086         * @version 1.87, 05/05/07
087         *
088         * @see DigestInputStream
089         * @see DigestOutputStream
090         */
091
092        public abstract class MessageDigest extends MessageDigestSpi {
093
094            private String algorithm;
095
096            // The state of this digest
097            private static final int INITIAL = 0;
098            private static final int IN_PROGRESS = 1;
099            private int state = INITIAL;
100
101            // The provider
102            private Provider provider;
103
104            /**
105             * Creates a message digest with the specified algorithm name.
106             * 
107             * @param algorithm the standard name of the digest algorithm. 
108             * See Appendix A in the <a href=
109             * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
110             * Java Cryptography Architecture API Specification &amp; Reference </a> 
111             * for information about standard algorithm names.
112             */
113            protected MessageDigest(String algorithm) {
114                this .algorithm = algorithm;
115            }
116
117            /**
118             * Returns a MessageDigest object that implements the specified digest
119             * algorithm.
120             *
121             * <p> This method traverses the list of registered security Providers,
122             * starting with the most preferred Provider.
123             * A new MessageDigest object encapsulating the
124             * MessageDigestSpi implementation from the first
125             * Provider that supports the specified algorithm is returned.
126             *
127             * <p> Note that the list of registered providers may be retrieved via
128             * the {@link Security#getProviders() Security.getProviders()} method.
129             *
130             * @param algorithm the name of the algorithm requested. 
131             * See Appendix A in the <a href=
132             * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
133             * Java Cryptography Architecture API Specification &amp; Reference </a> 
134             * for information about standard algorithm names.
135             *
136             * @return a Message Digest object that implements the specified algorithm.
137             *
138             * @exception NoSuchAlgorithmException if no Provider supports a
139             *		MessageDigestSpi implementation for the
140             *		specified algorithm.
141             *
142             * @see Provider
143             */
144            public static MessageDigest getInstance(String algorithm)
145                    throws NoSuchAlgorithmException {
146                try {
147                    Object[] objs = Security.getImpl(algorithm,
148                            "MessageDigest", (String) null);
149                    if (objs[0] instanceof  MessageDigest) {
150                        MessageDigest md = (MessageDigest) objs[0];
151                        md.provider = (Provider) objs[1];
152                        return md;
153                    } else {
154                        MessageDigest delegate = new Delegate(
155                                (MessageDigestSpi) objs[0], algorithm);
156                        delegate.provider = (Provider) objs[1];
157                        return delegate;
158                    }
159                } catch (NoSuchProviderException e) {
160                    throw new NoSuchAlgorithmException(algorithm + " not found");
161                }
162            }
163
164            /**
165             * Returns a MessageDigest object that implements the specified digest
166             * algorithm.
167             *
168             * <p> A new MessageDigest object encapsulating the
169             * MessageDigestSpi implementation from the specified provider
170             * is returned.  The specified provider must be registered
171             * in the security provider list.
172             *
173             * <p> Note that the list of registered providers may be retrieved via
174             * the {@link Security#getProviders() Security.getProviders()} method.
175             *
176             * @param algorithm the name of the algorithm requested. 
177             * See Appendix A in the <a href=
178             * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
179             * Java Cryptography Architecture API Specification &amp; Reference </a> 
180             * for information about standard algorithm names.
181             *
182             * @param provider the name of the provider.
183             *
184             * @return a MessageDigest object that implements the specified algorithm.
185             *
186             * @exception NoSuchAlgorithmException if a MessageDigestSpi
187             *		implementation for the specified algorithm is not
188             *		available from the specified provider.
189             *
190             * @exception NoSuchProviderException if the specified provider is not
191             *		registered in the security provider list.
192             *
193             * @exception IllegalArgumentException if the provider name is null
194             *		or empty.
195             *
196             * @see Provider 
197             */
198            public static MessageDigest getInstance(String algorithm,
199                    String provider) throws NoSuchAlgorithmException,
200                    NoSuchProviderException {
201                if (provider == null || provider.length() == 0)
202                    throw new IllegalArgumentException("missing provider");
203                Object[] objs = Security.getImpl(algorithm, "MessageDigest",
204                        provider);
205                if (objs[0] instanceof  MessageDigest) {
206                    MessageDigest md = (MessageDigest) objs[0];
207                    md.provider = (Provider) objs[1];
208                    return md;
209                } else {
210                    MessageDigest delegate = new Delegate(
211                            (MessageDigestSpi) objs[0], algorithm);
212                    delegate.provider = (Provider) objs[1];
213                    return delegate;
214                }
215            }
216
217            /**
218             * Returns a MessageDigest object that implements the specified digest
219             * algorithm.
220             *
221             * <p> A new MessageDigest object encapsulating the
222             * MessageDigestSpi implementation from the specified Provider
223             * object is returned.  Note that the specified Provider object
224             * does not have to be registered in the provider list.
225             *
226             * @param algorithm the name of the algorithm requested. 
227             * See Appendix A in the <a href=
228             * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
229             * Java Cryptography Architecture API Specification &amp; Reference </a> 
230             * for information about standard algorithm names.
231             *
232             * @param provider the provider.
233             *
234             * @return a MessageDigest object that implements the specified algorithm.
235             *
236             * @exception NoSuchAlgorithmException if a MessageDigestSpi
237             *		implementation for the specified algorithm is not available
238             *		from the specified Provider object.
239             *
240             * @exception IllegalArgumentException if the specified provider is null.
241             *
242             * @see Provider
243             *
244             * @since 1.4
245             */
246            public static MessageDigest getInstance(String algorithm,
247                    Provider provider) throws NoSuchAlgorithmException {
248                if (provider == null)
249                    throw new IllegalArgumentException("missing provider");
250                Object[] objs = Security.getImpl(algorithm, "MessageDigest",
251                        provider);
252                if (objs[0] instanceof  MessageDigest) {
253                    MessageDigest md = (MessageDigest) objs[0];
254                    md.provider = (Provider) objs[1];
255                    return md;
256                } else {
257                    MessageDigest delegate = new Delegate(
258                            (MessageDigestSpi) objs[0], algorithm);
259                    delegate.provider = (Provider) objs[1];
260                    return delegate;
261                }
262            }
263
264            /** 
265             * Returns the provider of this message digest object.
266             * 
267             * @return the provider of this message digest object
268             */
269            public final Provider getProvider() {
270                return this .provider;
271            }
272
273            /**
274             * Updates the digest using the specified byte.    
275             * 
276             * @param input the byte with which to update the digest.
277             */
278            public void update(byte input) {
279                engineUpdate(input);
280                state = IN_PROGRESS;
281            }
282
283            /**
284             * Updates the digest using the specified array of bytes, starting
285             * at the specified offset.
286             * 
287             * @param input the array of bytes.
288             *
289             * @param offset the offset to start from in the array of bytes.
290             *
291             * @param len the number of bytes to use, starting at 
292             * <code>offset</code>.  
293             */
294            public void update(byte[] input, int offset, int len) {
295                if (input == null) {
296                    throw new IllegalArgumentException("No input buffer given");
297                }
298                if (input.length - offset < len) {
299                    throw new IllegalArgumentException("Input buffer too short");
300                }
301                engineUpdate(input, offset, len);
302                state = IN_PROGRESS;
303            }
304
305            /**
306             * Updates the digest using the specified array of bytes.
307             * 
308             * @param input the array of bytes.
309             */
310            public void update(byte[] input) {
311                engineUpdate(input, 0, input.length);
312                state = IN_PROGRESS;
313            }
314
315            /**
316             * Update the digest using the specified ByteBuffer. The digest is
317             * updated using the <code>input.remaining()</code> bytes starting
318             * at <code>input.position()</code>.
319             * Upon return, the buffer's position will be equal to its limit;
320             * its limit will not have changed.
321             *
322             * @param input the ByteBuffer
323             * @since 1.5
324             */
325            public final void update(ByteBuffer input) {
326                if (input == null) {
327                    throw new NullPointerException();
328                }
329                engineUpdate(input);
330                state = IN_PROGRESS;
331            }
332
333            /**
334             * Completes the hash computation by performing final operations
335             * such as padding. The digest is reset after this call is made.
336             *
337             * @return the array of bytes for the resulting hash value.  
338             */
339            public byte[] digest() {
340                /* Resetting is the responsibility of implementors. */
341                byte[] result = engineDigest();
342                state = INITIAL;
343                return result;
344            }
345
346            /**
347             * Completes the hash computation by performing final operations
348             * such as padding. The digest is reset after this call is made.
349             *
350             * @param buf output buffer for the computed digest
351             *
352             * @param offset offset into the output buffer to begin storing the digest
353             *
354             * @param len number of bytes within buf allotted for the digest
355             *
356             * @return the number of bytes placed into <code>buf</code>
357             * 
358             * @exception DigestException if an error occurs.
359             */
360            public int digest(byte[] buf, int offset, int len)
361                    throws DigestException {
362                if (buf == null) {
363                    throw new IllegalArgumentException("No output buffer given");
364                }
365                if (buf.length - offset < len) {
366                    throw new IllegalArgumentException(
367                            "Output buffer too small for specified offset and length");
368                }
369                int numBytes = engineDigest(buf, offset, len);
370                state = INITIAL;
371                return numBytes;
372            }
373
374            /**
375             * Performs a final update on the digest using the specified array 
376             * of bytes, then completes the digest computation. That is, this
377             * method first calls {@link #update(byte[]) update(input)},
378             * passing the <i>input</i> array to the <code>update</code> method,
379             * then calls {@link #digest() digest()}.
380             *
381             * @param input the input to be updated before the digest is
382             * completed.
383             *
384             * @return the array of bytes for the resulting hash value.  
385             */
386            public byte[] digest(byte[] input) {
387                update(input);
388                return digest();
389            }
390
391            /**
392             * Returns a string representation of this message digest object.  
393             */
394            public String toString() {
395                ByteArrayOutputStream baos = new ByteArrayOutputStream();
396                PrintStream p = new PrintStream(baos);
397                p.print(algorithm + " Message Digest from "
398                        + provider.getName() + ", ");
399                switch (state) {
400                case INITIAL:
401                    p.print("<initialized>");
402                    break;
403                case IN_PROGRESS:
404                    p.print("<in progress>");
405                    break;
406                }
407                p.println();
408                return (baos.toString());
409            }
410
411            /**
412             * Compares two digests for equality. Does a simple byte compare.
413             * 
414             * @param digesta one of the digests to compare.
415             * 
416             * @param digestb the other digest to compare.    
417             *
418             * @return true if the digests are equal, false otherwise.
419             */
420            public static boolean isEqual(byte digesta[], byte digestb[]) {
421                if (digesta.length != digestb.length)
422                    return false;
423
424                for (int i = 0; i < digesta.length; i++) {
425                    if (digesta[i] != digestb[i]) {
426                        return false;
427                    }
428                }
429                return true;
430            }
431
432            /**
433             * Resets the digest for further use.
434             */
435            public void reset() {
436                engineReset();
437                state = INITIAL;
438            }
439
440            /** 
441             * Returns a string that identifies the algorithm, independent of
442             * implementation details. The name should be a standard
443             * Java Security name (such as "SHA", "MD5", and so on). 
444             * See Appendix A in the <a href=
445             * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
446             * Java Cryptography Architecture API Specification &amp; Reference </a> 
447             * for information about standard algorithm names.
448             *
449             * @return the name of the algorithm
450             */
451            public final String getAlgorithm() {
452                return this .algorithm;
453            }
454
455            /** 
456             * Returns the length of the digest in bytes, or 0 if this operation is
457             * not supported by the provider and the implementation is not cloneable.
458             *
459             * @return the digest length in bytes, or 0 if this operation is not
460             * supported by the provider and the implementation is not cloneable.
461             * 
462             * @since 1.2
463             */
464            public final int getDigestLength() {
465                int digestLen = engineGetDigestLength();
466                if (digestLen == 0) {
467                    try {
468                        MessageDigest md = (MessageDigest) clone();
469                        byte[] digest = md.digest();
470                        return digest.length;
471                    } catch (CloneNotSupportedException e) {
472                        return digestLen;
473                    }
474                }
475                return digestLen;
476            }
477
478            /**    
479             * Returns a clone if the implementation is cloneable.    
480             * 
481             * @return a clone if the implementation is cloneable.
482             *
483             * @exception CloneNotSupportedException if this is called on an
484             * implementation that does not support <code>Cloneable</code>.
485             */
486            public Object clone() throws CloneNotSupportedException {
487                if (this  instanceof  Cloneable) {
488                    return super .clone();
489                } else {
490                    throw new CloneNotSupportedException();
491                }
492            }
493
494            /*
495             * The following class allows providers to extend from MessageDigestSpi
496             * rather than from MessageDigest. It represents a MessageDigest with an
497             * encapsulated, provider-supplied SPI object (of type MessageDigestSpi).
498             * If the provider implementation is an instance of MessageDigestSpi,
499             * the getInstance() methods above return an instance of this class, with
500             * the SPI object encapsulated.
501             *
502             * Note: All SPI methods from the original MessageDigest class have been
503             * moved up the hierarchy into a new class (MessageDigestSpi), which has
504             * been interposed in the hierarchy between the API (MessageDigest)
505             * and its original parent (Object).
506             */
507
508            static class Delegate extends MessageDigest {
509
510                // The provider implementation (delegate)
511                private MessageDigestSpi digestSpi;
512
513                // constructor
514                public Delegate(MessageDigestSpi digestSpi, String algorithm) {
515                    super (algorithm);
516                    this .digestSpi = digestSpi;
517                }
518
519                /**
520                 * Returns a clone if the delegate is cloneable.    
521                 * 
522                 * @return a clone if the delegate is cloneable.
523                 *
524                 * @exception CloneNotSupportedException if this is called on a
525                 * delegate that does not support <code>Cloneable</code>.
526                 */
527                public Object clone() throws CloneNotSupportedException {
528                    if (digestSpi instanceof  Cloneable) {
529                        MessageDigestSpi digestSpiClone = (MessageDigestSpi) digestSpi
530                                .clone();
531                        // Because 'algorithm', 'provider', and 'state' are private
532                        // members of our supertype, we must perform a cast to
533                        // access them.
534                        MessageDigest that = new Delegate(digestSpiClone,
535                                ((MessageDigest) this ).algorithm);
536                        that.provider = ((MessageDigest) this ).provider;
537                        that.state = ((MessageDigest) this ).state;
538                        return that;
539                    } else {
540                        throw new CloneNotSupportedException();
541                    }
542                }
543
544                protected int engineGetDigestLength() {
545                    return digestSpi.engineGetDigestLength();
546                }
547
548                protected void engineUpdate(byte input) {
549                    digestSpi.engineUpdate(input);
550                }
551
552                protected void engineUpdate(byte[] input, int offset, int len) {
553                    digestSpi.engineUpdate(input, offset, len);
554                }
555
556                protected void engineUpdate(ByteBuffer input) {
557                    digestSpi.engineUpdate(input);
558                }
559
560                protected byte[] engineDigest() {
561                    return digestSpi.engineDigest();
562                }
563
564                protected int engineDigest(byte[] buf, int offset, int len)
565                        throws DigestException {
566                    return digestSpi.engineDigest(buf, offset, len);
567                }
568
569                protected void engineReset() {
570                    digestSpi.engineReset();
571                }
572            }
573        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.