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