View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.codec.digest;
19  
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.security.MessageDigest;
23  import java.security.NoSuchAlgorithmException;
24  
25  import org.apache.commons.codec.binary.Hex;
26  import org.apache.commons.codec.binary.StringUtils;
27  
28  /**
29   * Operations to simplify common {@link java.security.MessageDigest} tasks.
30   * This class is immutable and thread-safe.
31   *
32   * @version $Id: DigestUtils.html 891688 2013-12-24 20:49:46Z ggregory $
33   */
34  public class DigestUtils {
35  
36      private static final int STREAM_BUFFER_LENGTH = 1024;
37  
38      /**
39       * Read through an InputStream and returns the digest for the data
40       *
41       * @param digest
42       *            The MessageDigest to use (e.g. MD5)
43       * @param data
44       *            Data to digest
45       * @return the digest
46       * @throws IOException
47       *             On error reading from the stream
48       */
49      private static byte[] digest(final MessageDigest digest, final InputStream data) throws IOException {
50          return updateDigest(digest, data).digest();
51      }
52  
53      /**
54       * Returns a <code>MessageDigest</code> for the given <code>algorithm</code>.
55       *
56       * @param algorithm
57       *            the name of the algorithm requested. See <a
58       *            href="http://java.sun.com/j2se/1.3/docs/guide/security/CryptoSpec.html#AppA">Appendix A in the Java
59       *            Cryptography Architecture API Specification & Reference</a> for information about standard algorithm
60       *            names.
61       * @return A digest instance.
62       * @see MessageDigest#getInstance(String)
63       * @throws IllegalArgumentException
64       *             when a {@link NoSuchAlgorithmException} is caught.
65       */
66      public static MessageDigest getDigest(final String algorithm) {
67          try {
68              return MessageDigest.getInstance(algorithm);
69          } catch (final NoSuchAlgorithmException e) {
70              throw new IllegalArgumentException(e);
71          }
72      }
73  
74      /**
75       * Returns an MD2 MessageDigest.
76       *
77       * @return An MD2 digest instance.
78       * @throws IllegalArgumentException
79       *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because MD2 is a
80       *             built-in algorithm
81       * @see MessageDigestAlgorithms#MD2
82       * @since 1.7
83       */
84      public static MessageDigest getMd2Digest() {
85          return getDigest(MessageDigestAlgorithms.MD2);
86      }
87  
88      /**
89       * Returns an MD5 MessageDigest.
90       *
91       * @return An MD5 digest instance.
92       * @throws IllegalArgumentException
93       *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because MD5 is a
94       *             built-in algorithm
95       * @see MessageDigestAlgorithms#MD5
96       */
97      public static MessageDigest getMd5Digest() {
98          return getDigest(MessageDigestAlgorithms.MD5);
99      }
100 
101     /**
102      * Returns an SHA-1 digest.
103      *
104      * @return An SHA-1 digest instance.
105      * @throws IllegalArgumentException
106      *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-1 is a
107      *             built-in algorithm
108      * @see MessageDigestAlgorithms#SHA_1
109      * @since 1.7
110      */
111     public static MessageDigest getSha1Digest() {
112         return getDigest(MessageDigestAlgorithms.SHA_1);
113     }
114 
115     /**
116      * Returns an SHA-256 digest.
117      * <p>
118      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
119      * </p>
120      *
121      * @return An SHA-256 digest instance.
122      * @throws IllegalArgumentException
123      *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-256 is a
124      *             built-in algorithm
125      * @see MessageDigestAlgorithms#SHA_256
126      */
127     public static MessageDigest getSha256Digest() {
128         return getDigest(MessageDigestAlgorithms.SHA_256);
129     }
130 
131     /**
132      * Returns an SHA-384 digest.
133      * <p>
134      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
135      * </p>
136      *
137      * @return An SHA-384 digest instance.
138      * @throws IllegalArgumentException
139      *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-384 is a
140      *             built-in algorithm
141      * @see MessageDigestAlgorithms#SHA_384
142      */
143     public static MessageDigest getSha384Digest() {
144         return getDigest(MessageDigestAlgorithms.SHA_384);
145     }
146 
147     /**
148      * Returns an SHA-512 digest.
149      * <p>
150      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
151      * </p>
152      *
153      * @return An SHA-512 digest instance.
154      * @throws IllegalArgumentException
155      *             when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-512 is a
156      *             built-in algorithm
157      * @see MessageDigestAlgorithms#SHA_512
158      */
159     public static MessageDigest getSha512Digest() {
160         return getDigest(MessageDigestAlgorithms.SHA_512);
161     }
162 
163     /**
164      * Returns an SHA-1 digest.
165      *
166      * @return An SHA-1 digest instance.
167      * @throws IllegalArgumentException
168      *             when a {@link NoSuchAlgorithmException} is caught
169      * @deprecated Use {@link #getSha1Digest()}
170      */
171     @Deprecated
172     public static MessageDigest getShaDigest() {
173         return getSha1Digest();
174     }
175 
176     /**
177      * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
178      *
179      * @param data
180      *            Data to digest
181      * @return MD2 digest
182      * @since 1.7
183      */
184     public static byte[] md2(final byte[] data) {
185         return getMd2Digest().digest(data);
186     }
187 
188     /**
189      * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
190      *
191      * @param data
192      *            Data to digest
193      * @return MD2 digest
194      * @throws IOException
195      *             On error reading from the stream
196      * @since 1.7
197      */
198     public static byte[] md2(final InputStream data) throws IOException {
199         return digest(getMd2Digest(), data);
200     }
201 
202     /**
203      * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
204      *
205      * @param data
206      *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
207      * @return MD2 digest
208      * @since 1.7
209      */
210     public static byte[] md2(final String data) {
211         return md2(StringUtils.getBytesUtf8(data));
212     }
213 
214     /**
215      * Calculates the MD2 digest and returns the value as a 32 character hex string.
216      *
217      * @param data
218      *            Data to digest
219      * @return MD2 digest as a hex string
220      * @since 1.7
221      */
222     public static String md2Hex(final byte[] data) {
223         return Hex.encodeHexString(md2(data));
224     }
225 
226     /**
227      * Calculates the MD2 digest and returns the value as a 32 character hex string.
228      *
229      * @param data
230      *            Data to digest
231      * @return MD2 digest as a hex string
232      * @throws IOException
233      *             On error reading from the stream
234      * @since 1.7
235      */
236     public static String md2Hex(final InputStream data) throws IOException {
237         return Hex.encodeHexString(md2(data));
238     }
239 
240     /**
241      * Calculates the MD2 digest and returns the value as a 32 character hex string.
242      *
243      * @param data
244      *            Data to digest
245      * @return MD2 digest as a hex string
246      * @since 1.7
247      */
248     public static String md2Hex(final String data) {
249         return Hex.encodeHexString(md2(data));
250     }
251 
252     /**
253      * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
254      *
255      * @param data
256      *            Data to digest
257      * @return MD5 digest
258      */
259     public static byte[] md5(final byte[] data) {
260         return getMd5Digest().digest(data);
261     }
262 
263     /**
264      * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
265      *
266      * @param data
267      *            Data to digest
268      * @return MD5 digest
269      * @throws IOException
270      *             On error reading from the stream
271      * @since 1.4
272      */
273     public static byte[] md5(final InputStream data) throws IOException {
274         return digest(getMd5Digest(), data);
275     }
276 
277     /**
278      * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
279      *
280      * @param data
281      *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
282      * @return MD5 digest
283      */
284     public static byte[] md5(final String data) {
285         return md5(StringUtils.getBytesUtf8(data));
286     }
287 
288     /**
289      * Calculates the MD5 digest and returns the value as a 32 character hex string.
290      *
291      * @param data
292      *            Data to digest
293      * @return MD5 digest as a hex string
294      */
295     public static String md5Hex(final byte[] data) {
296         return Hex.encodeHexString(md5(data));
297     }
298 
299     /**
300      * Calculates the MD5 digest and returns the value as a 32 character hex string.
301      *
302      * @param data
303      *            Data to digest
304      * @return MD5 digest as a hex string
305      * @throws IOException
306      *             On error reading from the stream
307      * @since 1.4
308      */
309     public static String md5Hex(final InputStream data) throws IOException {
310         return Hex.encodeHexString(md5(data));
311     }
312 
313     /**
314      * Calculates the MD5 digest and returns the value as a 32 character hex string.
315      *
316      * @param data
317      *            Data to digest
318      * @return MD5 digest as a hex string
319      */
320     public static String md5Hex(final String data) {
321         return Hex.encodeHexString(md5(data));
322     }
323 
324     /**
325      * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
326      *
327      * @param data
328      *            Data to digest
329      * @return SHA-1 digest
330      * @deprecated Use {@link #sha1(byte[])}
331      */
332     @Deprecated
333     public static byte[] sha(final byte[] data) {
334         return sha1(data);
335     }
336 
337     /**
338      * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
339      *
340      * @param data
341      *            Data to digest
342      * @return SHA-1 digest
343      * @throws IOException
344      *             On error reading from the stream
345      * @since 1.4
346      * @deprecated Use {@link #sha1(InputStream)}
347      */
348     @Deprecated
349     public static byte[] sha(final InputStream data) throws IOException {
350         return sha1(data);
351     }
352 
353     /**
354      * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
355      *
356      * @param data
357      *            Data to digest
358      * @return SHA-1 digest
359      * @deprecated Use {@link #sha1(String)}
360      */
361     @Deprecated
362     public static byte[] sha(final String data) {
363         return sha1(data);
364     }
365 
366     /**
367      * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
368      *
369      * @param data
370      *            Data to digest
371      * @return SHA-1 digest
372      * @since 1.7
373      */
374     public static byte[] sha1(final byte[] data) {
375         return getSha1Digest().digest(data);
376     }
377 
378     /**
379      * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
380      *
381      * @param data
382      *            Data to digest
383      * @return SHA-1 digest
384      * @throws IOException
385      *             On error reading from the stream
386      * @since 1.7
387      */
388     public static byte[] sha1(final InputStream data) throws IOException {
389         return digest(getSha1Digest(), data);
390     }
391 
392     /**
393      * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
394      *
395      * @param data
396      *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
397      * @return SHA-1 digest
398      */
399     public static byte[] sha1(final String data) {
400         return sha1(StringUtils.getBytesUtf8(data));
401     }
402 
403     /**
404      * Calculates the SHA-1 digest and returns the value as a hex string.
405      *
406      * @param data
407      *            Data to digest
408      * @return SHA-1 digest as a hex string
409      * @since 1.7
410      */
411     public static String sha1Hex(final byte[] data) {
412         return Hex.encodeHexString(sha1(data));
413     }
414 
415     /**
416      * Calculates the SHA-1 digest and returns the value as a hex string.
417      *
418      * @param data
419      *            Data to digest
420      * @return SHA-1 digest as a hex string
421      * @throws IOException
422      *             On error reading from the stream
423      * @since 1.7
424      */
425     public static String sha1Hex(final InputStream data) throws IOException {
426         return Hex.encodeHexString(sha1(data));
427     }
428 
429     /**
430      * Calculates the SHA-1 digest and returns the value as a hex string.
431      *
432      * @param data
433      *            Data to digest
434      * @return SHA-1 digest as a hex string
435      * @since 1.7
436      */
437     public static String sha1Hex(final String data) {
438         return Hex.encodeHexString(sha1(data));
439     }
440 
441     /**
442      * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
443      * <p>
444      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
445      * </p>
446      *
447      * @param data
448      *            Data to digest
449      * @return SHA-256 digest
450      * @since 1.4
451      */
452     public static byte[] sha256(final byte[] data) {
453         return getSha256Digest().digest(data);
454     }
455 
456     /**
457      * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
458      * <p>
459      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
460      * </p>
461      *
462      * @param data
463      *            Data to digest
464      * @return SHA-256 digest
465      * @throws IOException
466      *             On error reading from the stream
467      * @since 1.4
468      */
469     public static byte[] sha256(final InputStream data) throws IOException {
470         return digest(getSha256Digest(), data);
471     }
472 
473     /**
474      * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
475      * <p>
476      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
477      * </p>
478      *
479      * @param data
480      *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
481      * @return SHA-256 digest
482      * @since 1.4
483      */
484     public static byte[] sha256(final String data) {
485         return sha256(StringUtils.getBytesUtf8(data));
486     }
487 
488     /**
489      * Calculates the SHA-256 digest and returns the value as a hex string.
490      * <p>
491      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
492      * </p>
493      *
494      * @param data
495      *            Data to digest
496      * @return SHA-256 digest as a hex string
497      * @since 1.4
498      */
499     public static String sha256Hex(final byte[] data) {
500         return Hex.encodeHexString(sha256(data));
501     }
502 
503     /**
504      * Calculates the SHA-256 digest and returns the value as a hex string.
505      * <p>
506      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
507      * </p>
508      *
509      * @param data
510      *            Data to digest
511      * @return SHA-256 digest as a hex string
512      * @throws IOException
513      *             On error reading from the stream
514      * @since 1.4
515      */
516     public static String sha256Hex(final InputStream data) throws IOException {
517         return Hex.encodeHexString(sha256(data));
518     }
519 
520     /**
521      * Calculates the SHA-256 digest and returns the value as a hex string.
522      * <p>
523      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
524      * </p>
525      *
526      * @param data
527      *            Data to digest
528      * @return SHA-256 digest as a hex string
529      * @since 1.4
530      */
531     public static String sha256Hex(final String data) {
532         return Hex.encodeHexString(sha256(data));
533     }
534 
535     /**
536      * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
537      * <p>
538      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
539      * </p>
540      *
541      * @param data
542      *            Data to digest
543      * @return SHA-384 digest
544      * @since 1.4
545      */
546     public static byte[] sha384(final byte[] data) {
547         return getSha384Digest().digest(data);
548     }
549 
550     /**
551      * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
552      * <p>
553      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
554      * </p>
555      *
556      * @param data
557      *            Data to digest
558      * @return SHA-384 digest
559      * @throws IOException
560      *             On error reading from the stream
561      * @since 1.4
562      */
563     public static byte[] sha384(final InputStream data) throws IOException {
564         return digest(getSha384Digest(), data);
565     }
566 
567     /**
568      * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
569      * <p>
570      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
571      * </p>
572      *
573      * @param data
574      *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
575      * @return SHA-384 digest
576      * @since 1.4
577      */
578     public static byte[] sha384(final String data) {
579         return sha384(StringUtils.getBytesUtf8(data));
580     }
581 
582     /**
583      * Calculates the SHA-384 digest and returns the value as a hex string.
584      * <p>
585      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
586      * </p>
587      *
588      * @param data
589      *            Data to digest
590      * @return SHA-384 digest as a hex string
591      * @since 1.4
592      */
593     public static String sha384Hex(final byte[] data) {
594         return Hex.encodeHexString(sha384(data));
595     }
596 
597     /**
598      * Calculates the SHA-384 digest and returns the value as a hex string.
599      * <p>
600      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
601      * </p>
602      *
603      * @param data
604      *            Data to digest
605      * @return SHA-384 digest as a hex string
606      * @throws IOException
607      *             On error reading from the stream
608      * @since 1.4
609      */
610     public static String sha384Hex(final InputStream data) throws IOException {
611         return Hex.encodeHexString(sha384(data));
612     }
613 
614     /**
615      * Calculates the SHA-384 digest and returns the value as a hex string.
616      * <p>
617      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
618      * </p>
619      *
620      * @param data
621      *            Data to digest
622      * @return SHA-384 digest as a hex string
623      * @since 1.4
624      */
625     public static String sha384Hex(final String data) {
626         return Hex.encodeHexString(sha384(data));
627     }
628 
629     /**
630      * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
631      * <p>
632      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
633      * </p>
634      *
635      * @param data
636      *            Data to digest
637      * @return SHA-512 digest
638      * @since 1.4
639      */
640     public static byte[] sha512(final byte[] data) {
641         return getSha512Digest().digest(data);
642     }
643 
644     /**
645      * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
646      * <p>
647      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
648      * </p>
649      *
650      * @param data
651      *            Data to digest
652      * @return SHA-512 digest
653      * @throws IOException
654      *             On error reading from the stream
655      * @since 1.4
656      */
657     public static byte[] sha512(final InputStream data) throws IOException {
658         return digest(getSha512Digest(), data);
659     }
660 
661     /**
662      * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
663      * <p>
664      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
665      * </p>
666      *
667      * @param data
668      *            Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
669      * @return SHA-512 digest
670      * @since 1.4
671      */
672     public static byte[] sha512(final String data) {
673         return sha512(StringUtils.getBytesUtf8(data));
674     }
675 
676     /**
677      * Calculates the SHA-512 digest and returns the value as a hex string.
678      * <p>
679      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
680      * </p>
681      *
682      * @param data
683      *            Data to digest
684      * @return SHA-512 digest as a hex string
685      * @since 1.4
686      */
687     public static String sha512Hex(final byte[] data) {
688         return Hex.encodeHexString(sha512(data));
689     }
690 
691     /**
692      * Calculates the SHA-512 digest and returns the value as a hex string.
693      * <p>
694      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
695      * </p>
696      *
697      * @param data
698      *            Data to digest
699      * @return SHA-512 digest as a hex string
700      * @throws IOException
701      *             On error reading from the stream
702      * @since 1.4
703      */
704     public static String sha512Hex(final InputStream data) throws IOException {
705         return Hex.encodeHexString(sha512(data));
706     }
707 
708     /**
709      * Calculates the SHA-512 digest and returns the value as a hex string.
710      * <p>
711      * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
712      * </p>
713      *
714      * @param data
715      *            Data to digest
716      * @return SHA-512 digest as a hex string
717      * @since 1.4
718      */
719     public static String sha512Hex(final String data) {
720         return Hex.encodeHexString(sha512(data));
721     }
722 
723     /**
724      * Calculates the SHA-1 digest and returns the value as a hex string.
725      *
726      * @param data
727      *            Data to digest
728      * @return SHA-1 digest as a hex string
729      * @deprecated Use {@link #sha1Hex(byte[])}
730      */
731     @Deprecated
732     public static String shaHex(final byte[] data) {
733         return sha1Hex(data);
734     }
735 
736     /**
737      * Calculates the SHA-1 digest and returns the value as a hex string.
738      *
739      * @param data
740      *            Data to digest
741      * @return SHA-1 digest as a hex string
742      * @throws IOException
743      *             On error reading from the stream
744      * @since 1.4
745      * @deprecated Use {@link #sha1Hex(InputStream)}
746      */
747     @Deprecated
748     public static String shaHex(final InputStream data) throws IOException {
749         return sha1Hex(data);
750     }
751 
752     /**
753      * Calculates the SHA-1 digest and returns the value as a hex string.
754      *
755      * @param data
756      *            Data to digest
757      * @return SHA-1 digest as a hex string
758      * @deprecated Use {@link #sha1Hex(String)}
759      */
760     @Deprecated
761     public static String shaHex(final String data) {
762         return sha1Hex(data);
763     }
764 
765     /**
766      * Updates the given {@link MessageDigest}.
767      *
768      * @param messageDigest
769      *            the {@link MessageDigest} to update
770      * @param valueToDigest
771      *            the value to update the {@link MessageDigest} with
772      * @return the updated {@link MessageDigest}
773      * @since 1.7
774      */
775     public static MessageDigest updateDigest(final MessageDigest messageDigest, final byte[] valueToDigest) {
776         messageDigest.update(valueToDigest);
777         return messageDigest;
778     }
779 
780     /**
781      * Reads through an InputStream and updates the digest for the data
782      *
783      * @param digest
784      *            The MessageDigest to use (e.g. MD5)
785      * @param data
786      *            Data to digest
787      * @return the digest
788      * @throws IOException
789      *             On error reading from the stream
790      * @since 1.8
791      */
792     public static MessageDigest updateDigest(final MessageDigest digest, final InputStream data) throws IOException {
793         final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
794         int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
795 
796         while (read > -1) {
797             digest.update(buffer, 0, read);
798             read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
799         }
800 
801         return digest;
802     }
803 
804     /**
805      * Updates the given {@link MessageDigest}.
806      *
807      * @param messageDigest
808      *            the {@link MessageDigest} to update
809      * @param valueToDigest
810      *            the value to update the {@link MessageDigest} with;
811      *            converted to bytes using {@link StringUtils#getBytesUtf8(String)}
812      * @return the updated {@link MessageDigest}
813      * @since 1.7
814      */
815     public static MessageDigest updateDigest(final MessageDigest messageDigest, final String valueToDigest) {
816         messageDigest.update(StringUtils.getBytesUtf8(valueToDigest));
817         return messageDigest;
818     }
819 }