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.BufferedInputStream;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.nio.ByteBuffer;
26 import java.security.MessageDigest;
27 import java.security.NoSuchAlgorithmException;
28
29 import org.apache.commons.codec.binary.Hex;
30 import org.apache.commons.codec.binary.StringUtils;
31
32 /**
33 * Operations to simplify common {@link java.security.MessageDigest} tasks.
34 * This class is immutable and thread-safe.
35 * However the MessageDigest instances it creates generally won't be.
36 * <p>
37 * The {@link MessageDigestAlgorithms} class provides constants for standard
38 * digest algorithms that can be used with the {@link #getDigest(String)} method
39 * and other methods that require the Digest algorithm name.
40 * <p>
41 * Note: the class has short-hand methods for all the algorithms present as standard in Java 6.
42 * This approach requires lots of methods for each algorithm, and quickly becomes unwieldy.
43 * The following code works with all algorithms:
44 * <pre>
45 * import static org.apache.commons.codec.digest.MessageDigestAlgorithms.SHA_224;
46 * ...
47 * byte [] digest = new DigestUtils(SHA_224).digest(dataToDigest);
48 * String hdigest = new DigestUtils(SHA_224).digestAsHex(new File("pom.xml"));
49 * </pre>
50 * @see MessageDigestAlgorithms
51 * @version $Id: DigestUtils.java 1811344 2017-10-06 15:19:57Z ggregory $
52 */
53 public class DigestUtils {
54
55 private static final int STREAM_BUFFER_LENGTH = 1024;
56
57 /**
58 * Reads through a byte array and returns the digest for the data. Provided for symmetry with other methods.
59 *
60 * @param messageDigest
61 * The MessageDigest to use (e.g. MD5)
62 * @param data
63 * Data to digest
64 * @return the digest
65 * @since 1.11
66 */
67 public static byte[] digest(final MessageDigest messageDigest, final byte[] data) {
68 return messageDigest.digest(data);
69 }
70
71 /**
72 * Reads through a ByteBuffer and returns the digest for the data
73 *
74 * @param messageDigest
75 * The MessageDigest to use (e.g. MD5)
76 * @param data
77 * Data to digest
78 * @return the digest
79 *
80 * @since 1.11
81 */
82 public static byte[] digest(final MessageDigest messageDigest, final ByteBuffer data) {
83 messageDigest.update(data);
84 return messageDigest.digest();
85 }
86
87 /**
88 * Reads through a File and returns the digest for the data
89 *
90 * @param messageDigest
91 * The MessageDigest to use (e.g. MD5)
92 * @param data
93 * Data to digest
94 * @return the digest
95 * @throws IOException
96 * On error reading from the stream
97 * @since 1.11
98 */
99 public static byte[] digest(final MessageDigest messageDigest, final File data) throws IOException {
100 return updateDigest(messageDigest, data).digest();
101 }
102
103 /**
104 * Reads through an InputStream and returns the digest for the data
105 *
106 * @param messageDigest
107 * The MessageDigest to use (e.g. MD5)
108 * @param data
109 * Data to digest
110 * @return the digest
111 * @throws IOException
112 * On error reading from the stream
113 * @since 1.11 (was private)
114 */
115 public static byte[] digest(final MessageDigest messageDigest, final InputStream data) throws IOException {
116 return updateDigest(messageDigest, data).digest();
117 }
118
119 /**
120 * Returns a <code>MessageDigest</code> for the given <code>algorithm</code>.
121 *
122 * @param algorithm
123 * the name of the algorithm requested. See <a
124 * href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA"
125 * >Appendix A in the Java Cryptography Architecture Reference Guide</a> for information about standard
126 * algorithm names.
127 * @return A digest instance.
128 * @see MessageDigest#getInstance(String)
129 * @throws IllegalArgumentException
130 * when a {@link NoSuchAlgorithmException} is caught.
131 */
132 public static MessageDigest getDigest(final String algorithm) {
133 try {
134 return MessageDigest.getInstance(algorithm);
135 } catch (final NoSuchAlgorithmException e) {
136 throw new IllegalArgumentException(e);
137 }
138 }
139
140 /**
141 * Returns a <code>MessageDigest</code> for the given <code>algorithm</code> or a default if there is a problem
142 * getting the algorithm.
143 *
144 * @param algorithm
145 * the name of the algorithm requested. See
146 * <a href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA" >
147 * Appendix A in the Java Cryptography Architecture Reference Guide</a> for information about standard
148 * algorithm names.
149 * @param defaultMessageDigest
150 * The default MessageDigest.
151 * @return A digest instance.
152 * @see MessageDigest#getInstance(String)
153 * @throws IllegalArgumentException
154 * when a {@link NoSuchAlgorithmException} is caught.
155 * @since 1.11
156 */
157 public static MessageDigest getDigest(final String algorithm, final MessageDigest defaultMessageDigest) {
158 try {
159 return MessageDigest.getInstance(algorithm);
160 } catch (final Exception e) {
161 return defaultMessageDigest;
162 }
163 }
164
165 /**
166 * Returns an MD2 MessageDigest.
167 *
168 * @return An MD2 digest instance.
169 * @throws IllegalArgumentException
170 * when a {@link NoSuchAlgorithmException} is caught, which should never happen because MD2 is a
171 * built-in algorithm
172 * @see MessageDigestAlgorithms#MD2
173 * @since 1.7
174 */
175 public static MessageDigest getMd2Digest() {
176 return getDigest(MessageDigestAlgorithms.MD2);
177 }
178
179 /**
180 * Returns an MD5 MessageDigest.
181 *
182 * @return An MD5 digest instance.
183 * @throws IllegalArgumentException
184 * when a {@link NoSuchAlgorithmException} is caught, which should never happen because MD5 is a
185 * built-in algorithm
186 * @see MessageDigestAlgorithms#MD5
187 */
188 public static MessageDigest getMd5Digest() {
189 return getDigest(MessageDigestAlgorithms.MD5);
190 }
191
192 /**
193 * Returns an SHA-1 digest.
194 *
195 * @return An SHA-1 digest instance.
196 * @throws IllegalArgumentException
197 * when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-1 is a
198 * built-in algorithm
199 * @see MessageDigestAlgorithms#SHA_1
200 * @since 1.7
201 */
202 public static MessageDigest getSha1Digest() {
203 return getDigest(MessageDigestAlgorithms.SHA_1);
204 }
205
206 /**
207 * Returns an SHA-256 digest.
208 * <p>
209 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
210 * </p>
211 *
212 * @return An SHA-256 digest instance.
213 * @throws IllegalArgumentException
214 * when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-256 is a
215 * built-in algorithm
216 * @see MessageDigestAlgorithms#SHA_256
217 */
218 public static MessageDigest getSha256Digest() {
219 return getDigest(MessageDigestAlgorithms.SHA_256);
220 }
221
222 /**
223 * Returns an SHA-384 digest.
224 * <p>
225 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
226 * </p>
227 *
228 * @return An SHA-384 digest instance.
229 * @throws IllegalArgumentException
230 * when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-384 is a
231 * built-in algorithm
232 * @see MessageDigestAlgorithms#SHA_384
233 */
234 public static MessageDigest getSha384Digest() {
235 return getDigest(MessageDigestAlgorithms.SHA_384);
236 }
237
238 /**
239 * Returns an SHA-512 digest.
240 * <p>
241 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
242 * </p>
243 *
244 * @return An SHA-512 digest instance.
245 * @throws IllegalArgumentException
246 * when a {@link NoSuchAlgorithmException} is caught, which should never happen because SHA-512 is a
247 * built-in algorithm
248 * @see MessageDigestAlgorithms#SHA_512
249 */
250 public static MessageDigest getSha512Digest() {
251 return getDigest(MessageDigestAlgorithms.SHA_512);
252 }
253
254 /**
255 * Returns an SHA-1 digest.
256 *
257 * @return An SHA-1 digest instance.
258 * @throws IllegalArgumentException
259 * when a {@link NoSuchAlgorithmException} is caught
260 * @deprecated (1.11) Use {@link #getSha1Digest()}
261 */
262 @Deprecated
263 public static MessageDigest getShaDigest() {
264 return getSha1Digest();
265 }
266
267 /**
268 * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
269 *
270 * @param data
271 * Data to digest
272 * @return MD2 digest
273 * @since 1.7
274 */
275 public static byte[] md2(final byte[] data) {
276 return getMd2Digest().digest(data);
277 }
278
279 /**
280 * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
281 *
282 * @param data
283 * Data to digest
284 * @return MD2 digest
285 * @throws IOException
286 * On error reading from the stream
287 * @since 1.7
288 */
289 public static byte[] md2(final InputStream data) throws IOException {
290 return digest(getMd2Digest(), data);
291 }
292
293 /**
294 * Calculates the MD2 digest and returns the value as a 16 element <code>byte[]</code>.
295 *
296 * @param data
297 * Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
298 * @return MD2 digest
299 * @since 1.7
300 */
301 public static byte[] md2(final String data) {
302 return md2(StringUtils.getBytesUtf8(data));
303 }
304
305 /**
306 * Calculates the MD2 digest and returns the value as a 32 character hex string.
307 *
308 * @param data
309 * Data to digest
310 * @return MD2 digest as a hex string
311 * @since 1.7
312 */
313 public static String md2Hex(final byte[] data) {
314 return Hex.encodeHexString(md2(data));
315 }
316
317 /**
318 * Calculates the MD2 digest and returns the value as a 32 character hex string.
319 *
320 * @param data
321 * Data to digest
322 * @return MD2 digest as a hex string
323 * @throws IOException
324 * On error reading from the stream
325 * @since 1.7
326 */
327 public static String md2Hex(final InputStream data) throws IOException {
328 return Hex.encodeHexString(md2(data));
329 }
330
331 /**
332 * Calculates the MD2 digest and returns the value as a 32 character hex string.
333 *
334 * @param data
335 * Data to digest
336 * @return MD2 digest as a hex string
337 * @since 1.7
338 */
339 public static String md2Hex(final String data) {
340 return Hex.encodeHexString(md2(data));
341 }
342
343 /**
344 * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
345 *
346 * @param data
347 * Data to digest
348 * @return MD5 digest
349 */
350 public static byte[] md5(final byte[] data) {
351 return getMd5Digest().digest(data);
352 }
353
354 /**
355 * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
356 *
357 * @param data
358 * Data to digest
359 * @return MD5 digest
360 * @throws IOException
361 * On error reading from the stream
362 * @since 1.4
363 */
364 public static byte[] md5(final InputStream data) throws IOException {
365 return digest(getMd5Digest(), data);
366 }
367
368 /**
369 * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.
370 *
371 * @param data
372 * Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
373 * @return MD5 digest
374 */
375 public static byte[] md5(final String data) {
376 return md5(StringUtils.getBytesUtf8(data));
377 }
378
379 /**
380 * Calculates the MD5 digest and returns the value as a 32 character hex string.
381 *
382 * @param data
383 * Data to digest
384 * @return MD5 digest as a hex string
385 */
386 public static String md5Hex(final byte[] data) {
387 return Hex.encodeHexString(md5(data));
388 }
389
390 /**
391 * Calculates the MD5 digest and returns the value as a 32 character hex string.
392 *
393 * @param data
394 * Data to digest
395 * @return MD5 digest as a hex string
396 * @throws IOException
397 * On error reading from the stream
398 * @since 1.4
399 */
400 public static String md5Hex(final InputStream data) throws IOException {
401 return Hex.encodeHexString(md5(data));
402 }
403
404 /**
405 * Calculates the MD5 digest and returns the value as a 32 character hex string.
406 *
407 * @param data
408 * Data to digest
409 * @return MD5 digest as a hex string
410 */
411 public static String md5Hex(final String data) {
412 return Hex.encodeHexString(md5(data));
413 }
414
415 /**
416 * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
417 *
418 * @param data
419 * Data to digest
420 * @return SHA-1 digest
421 * @deprecated (1.11) Use {@link #sha1(byte[])}
422 */
423 @Deprecated
424 public static byte[] sha(final byte[] data) {
425 return sha1(data);
426 }
427
428 /**
429 * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
430 *
431 * @param data
432 * Data to digest
433 * @return SHA-1 digest
434 * @throws IOException
435 * On error reading from the stream
436 * @since 1.4
437 * @deprecated (1.11) Use {@link #sha1(InputStream)}
438 */
439 @Deprecated
440 public static byte[] sha(final InputStream data) throws IOException {
441 return sha1(data);
442 }
443
444 /**
445 * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
446 *
447 * @param data
448 * Data to digest
449 * @return SHA-1 digest
450 * @deprecated (1.11) Use {@link #sha1(String)}
451 */
452 @Deprecated
453 public static byte[] sha(final String data) {
454 return sha1(data);
455 }
456
457 /**
458 * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
459 *
460 * @param data
461 * Data to digest
462 * @return SHA-1 digest
463 * @since 1.7
464 */
465 public static byte[] sha1(final byte[] data) {
466 return getSha1Digest().digest(data);
467 }
468
469 /**
470 * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
471 *
472 * @param data
473 * Data to digest
474 * @return SHA-1 digest
475 * @throws IOException
476 * On error reading from the stream
477 * @since 1.7
478 */
479 public static byte[] sha1(final InputStream data) throws IOException {
480 return digest(getSha1Digest(), data);
481 }
482
483 /**
484 * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>.
485 *
486 * @param data
487 * Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
488 * @return SHA-1 digest
489 */
490 public static byte[] sha1(final String data) {
491 return sha1(StringUtils.getBytesUtf8(data));
492 }
493
494 /**
495 * Calculates the SHA-1 digest and returns the value as a hex string.
496 *
497 * @param data
498 * Data to digest
499 * @return SHA-1 digest as a hex string
500 * @since 1.7
501 */
502 public static String sha1Hex(final byte[] data) {
503 return Hex.encodeHexString(sha1(data));
504 }
505
506 /**
507 * Calculates the SHA-1 digest and returns the value as a hex string.
508 *
509 * @param data
510 * Data to digest
511 * @return SHA-1 digest as a hex string
512 * @throws IOException
513 * On error reading from the stream
514 * @since 1.7
515 */
516 public static String sha1Hex(final InputStream data) throws IOException {
517 return Hex.encodeHexString(sha1(data));
518 }
519
520 /**
521 * Calculates the SHA-1 digest and returns the value as a hex string.
522 *
523 * @param data
524 * Data to digest
525 * @return SHA-1 digest as a hex string
526 * @since 1.7
527 */
528 public static String sha1Hex(final String data) {
529 return Hex.encodeHexString(sha1(data));
530 }
531
532 /**
533 * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
534 * <p>
535 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
536 * </p>
537 *
538 * @param data
539 * Data to digest
540 * @return SHA-256 digest
541 * @since 1.4
542 */
543 public static byte[] sha256(final byte[] data) {
544 return getSha256Digest().digest(data);
545 }
546
547 /**
548 * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
549 * <p>
550 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
551 * </p>
552 *
553 * @param data
554 * Data to digest
555 * @return SHA-256 digest
556 * @throws IOException
557 * On error reading from the stream
558 * @since 1.4
559 */
560 public static byte[] sha256(final InputStream data) throws IOException {
561 return digest(getSha256Digest(), data);
562 }
563
564 /**
565 * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>.
566 * <p>
567 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
568 * </p>
569 *
570 * @param data
571 * Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
572 * @return SHA-256 digest
573 * @since 1.4
574 */
575 public static byte[] sha256(final String data) {
576 return sha256(StringUtils.getBytesUtf8(data));
577 }
578
579 /**
580 * Calculates the SHA-256 digest and returns the value as a hex string.
581 * <p>
582 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
583 * </p>
584 *
585 * @param data
586 * Data to digest
587 * @return SHA-256 digest as a hex string
588 * @since 1.4
589 */
590 public static String sha256Hex(final byte[] data) {
591 return Hex.encodeHexString(sha256(data));
592 }
593
594 /**
595 * Calculates the SHA-256 digest and returns the value as a hex string.
596 * <p>
597 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
598 * </p>
599 *
600 * @param data
601 * Data to digest
602 * @return SHA-256 digest as a hex string
603 * @throws IOException
604 * On error reading from the stream
605 * @since 1.4
606 */
607 public static String sha256Hex(final InputStream data) throws IOException {
608 return Hex.encodeHexString(sha256(data));
609 }
610
611 /**
612 * Calculates the SHA-256 digest and returns the value as a hex string.
613 * <p>
614 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
615 * </p>
616 *
617 * @param data
618 * Data to digest
619 * @return SHA-256 digest as a hex string
620 * @since 1.4
621 */
622 public static String sha256Hex(final String data) {
623 return Hex.encodeHexString(sha256(data));
624 }
625
626 /**
627 * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
628 * <p>
629 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
630 * </p>
631 *
632 * @param data
633 * Data to digest
634 * @return SHA-384 digest
635 * @since 1.4
636 */
637 public static byte[] sha384(final byte[] data) {
638 return getSha384Digest().digest(data);
639 }
640
641 /**
642 * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
643 * <p>
644 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
645 * </p>
646 *
647 * @param data
648 * Data to digest
649 * @return SHA-384 digest
650 * @throws IOException
651 * On error reading from the stream
652 * @since 1.4
653 */
654 public static byte[] sha384(final InputStream data) throws IOException {
655 return digest(getSha384Digest(), data);
656 }
657
658 /**
659 * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>.
660 * <p>
661 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
662 * </p>
663 *
664 * @param data
665 * Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
666 * @return SHA-384 digest
667 * @since 1.4
668 */
669 public static byte[] sha384(final String data) {
670 return sha384(StringUtils.getBytesUtf8(data));
671 }
672
673 /**
674 * Calculates the SHA-384 digest and returns the value as a hex string.
675 * <p>
676 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
677 * </p>
678 *
679 * @param data
680 * Data to digest
681 * @return SHA-384 digest as a hex string
682 * @since 1.4
683 */
684 public static String sha384Hex(final byte[] data) {
685 return Hex.encodeHexString(sha384(data));
686 }
687
688 /**
689 * Calculates the SHA-384 digest and returns the value as a hex string.
690 * <p>
691 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
692 * </p>
693 *
694 * @param data
695 * Data to digest
696 * @return SHA-384 digest as a hex string
697 * @throws IOException
698 * On error reading from the stream
699 * @since 1.4
700 */
701 public static String sha384Hex(final InputStream data) throws IOException {
702 return Hex.encodeHexString(sha384(data));
703 }
704
705 /**
706 * Calculates the SHA-384 digest and returns the value as a hex string.
707 * <p>
708 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
709 * </p>
710 *
711 * @param data
712 * Data to digest
713 * @return SHA-384 digest as a hex string
714 * @since 1.4
715 */
716 public static String sha384Hex(final String data) {
717 return Hex.encodeHexString(sha384(data));
718 }
719
720 /**
721 * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
722 * <p>
723 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
724 * </p>
725 *
726 * @param data
727 * Data to digest
728 * @return SHA-512 digest
729 * @since 1.4
730 */
731 public static byte[] sha512(final byte[] data) {
732 return getSha512Digest().digest(data);
733 }
734
735 /**
736 * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
737 * <p>
738 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
739 * </p>
740 *
741 * @param data
742 * Data to digest
743 * @return SHA-512 digest
744 * @throws IOException
745 * On error reading from the stream
746 * @since 1.4
747 */
748 public static byte[] sha512(final InputStream data) throws IOException {
749 return digest(getSha512Digest(), data);
750 }
751
752 /**
753 * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>.
754 * <p>
755 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
756 * </p>
757 *
758 * @param data
759 * Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
760 * @return SHA-512 digest
761 * @since 1.4
762 */
763 public static byte[] sha512(final String data) {
764 return sha512(StringUtils.getBytesUtf8(data));
765 }
766
767 /**
768 * Calculates the SHA-512 digest and returns the value as a hex string.
769 * <p>
770 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
771 * </p>
772 *
773 * @param data
774 * Data to digest
775 * @return SHA-512 digest as a hex string
776 * @since 1.4
777 */
778 public static String sha512Hex(final byte[] data) {
779 return Hex.encodeHexString(sha512(data));
780 }
781
782 /**
783 * Calculates the SHA-512 digest and returns the value as a hex string.
784 * <p>
785 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
786 * </p>
787 *
788 * @param data
789 * Data to digest
790 * @return SHA-512 digest as a hex string
791 * @throws IOException
792 * On error reading from the stream
793 * @since 1.4
794 */
795 public static String sha512Hex(final InputStream data) throws IOException {
796 return Hex.encodeHexString(sha512(data));
797 }
798
799 /**
800 * Calculates the SHA-512 digest and returns the value as a hex string.
801 * <p>
802 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0.
803 * </p>
804 *
805 * @param data
806 * Data to digest
807 * @return SHA-512 digest as a hex string
808 * @since 1.4
809 */
810 public static String sha512Hex(final String data) {
811 return Hex.encodeHexString(sha512(data));
812 }
813
814 /**
815 * Calculates the SHA-1 digest and returns the value as a hex string.
816 *
817 * @param data
818 * Data to digest
819 * @return SHA-1 digest as a hex string
820 * @deprecated (1.11) Use {@link #sha1Hex(byte[])}
821 */
822 @Deprecated
823 public static String shaHex(final byte[] data) {
824 return sha1Hex(data);
825 }
826
827 /**
828 * Calculates the SHA-1 digest and returns the value as a hex string.
829 *
830 * @param data
831 * Data to digest
832 * @return SHA-1 digest as a hex string
833 * @throws IOException
834 * On error reading from the stream
835 * @since 1.4
836 * @deprecated (1.11) Use {@link #sha1Hex(InputStream)}
837 */
838 @Deprecated
839 public static String shaHex(final InputStream data) throws IOException {
840 return sha1Hex(data);
841 }
842
843 /**
844 * Calculates the SHA-1 digest and returns the value as a hex string.
845 *
846 * @param data
847 * Data to digest
848 * @return SHA-1 digest as a hex string
849 * @deprecated (1.11) Use {@link #sha1Hex(String)}
850 */
851 @Deprecated
852 public static String shaHex(final String data) {
853 return sha1Hex(data);
854 }
855
856 /**
857 * Updates the given {@link MessageDigest}.
858 *
859 * @param messageDigest
860 * the {@link MessageDigest} to update
861 * @param valueToDigest
862 * the value to update the {@link MessageDigest} with
863 * @return the updated {@link MessageDigest}
864 * @since 1.7
865 */
866 public static MessageDigest updateDigest(final MessageDigest messageDigest, final byte[] valueToDigest) {
867 messageDigest.update(valueToDigest);
868 return messageDigest;
869 }
870
871 /**
872 * Updates the given {@link MessageDigest}.
873 *
874 * @param messageDigest
875 * the {@link MessageDigest} to update
876 * @param valueToDigest
877 * the value to update the {@link MessageDigest} with
878 * @return the updated {@link MessageDigest}
879 * @since 1.11
880 */
881 public static MessageDigest updateDigest(final MessageDigest messageDigest, final ByteBuffer valueToDigest) {
882 messageDigest.update(valueToDigest);
883 return messageDigest;
884 }
885
886 /**
887 * Reads through a File and updates the digest for the data
888 *
889 * @param digest
890 * The MessageDigest to use (e.g. MD5)
891 * @param data
892 * Data to digest
893 * @return the digest
894 * @throws IOException
895 * On error reading from the stream
896 * @since 1.11
897 */
898 public static MessageDigest updateDigest(final MessageDigest digest, final File data) throws IOException {
899 final BufferedInputStream stream = new BufferedInputStream(new FileInputStream(data));
900 try {
901 return updateDigest(digest, stream);
902 } finally {
903 stream.close();
904 }
905 }
906
907 /**
908 * Reads through an InputStream and updates the digest for the data
909 *
910 * @param digest
911 * The MessageDigest to use (e.g. MD5)
912 * @param data
913 * Data to digest
914 * @return the digest
915 * @throws IOException
916 * On error reading from the stream
917 * @since 1.8
918 */
919 public static MessageDigest updateDigest(final MessageDigest digest, final InputStream data) throws IOException {
920 final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
921 int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
922
923 while (read > -1) {
924 digest.update(buffer, 0, read);
925 read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
926 }
927
928 return digest;
929 }
930
931 /**
932 * Updates the given {@link MessageDigest} from a String (converted to bytes using UTF-8).
933 * <p>
934 * To update the digest using a different charset for the conversion,
935 * convert the String to a byte array using
936 * {@link String#getBytes(java.nio.charset.Charset)} and pass that
937 * to the {@link DigestUtils#updateDigest(MessageDigest, byte[])} method
938 *
939 * @param messageDigest
940 * the {@link MessageDigest} to update
941 * @param valueToDigest
942 * the value to update the {@link MessageDigest} with;
943 * converted to bytes using {@link StringUtils#getBytesUtf8(String)}
944 * @return the updated {@link MessageDigest}
945 * @since 1.7
946 */
947 public static MessageDigest updateDigest(final MessageDigest messageDigest, final String valueToDigest) {
948 messageDigest.update(StringUtils.getBytesUtf8(valueToDigest));
949 return messageDigest;
950 }
951
952 /**
953 * Test whether the algorithm is supported.
954 * @param messageDigestAlgorithm the algorithm name
955 * @return {@code true} if the algorithm can be found
956 * @since 1.11
957 */
958 public static boolean isAvailable(final String messageDigestAlgorithm) {
959 return getDigest(messageDigestAlgorithm, null) != null;
960 }
961
962 private final MessageDigest messageDigest;
963
964 /**
965 * Preserves binary compatibity only.
966 * As for previous versions does not provide useful behaviour
967 * @deprecated since 1.11; only useful to preserve binary compatibility
968 */
969 @Deprecated
970 public DigestUtils() {
971 this.messageDigest = null;
972 }
973
974 /**
975 * Creates an instance using the provided {@link MessageDigest} parameter.
976 *
977 * This can then be used to create digests using methods such as
978 * {@link #digest(byte[])} and {@link #digestAsHex(File)}.
979 *
980 * @param digest the {@link MessageDigest} to use
981 * @since 1.11
982 */
983 public DigestUtils(final MessageDigest digest) {
984 this.messageDigest = digest;
985 }
986
987 /**
988 * Creates an instance using the provided {@link MessageDigest} parameter.
989 *
990 * This can then be used to create digests using methods such as
991 * {@link #digest(byte[])} and {@link #digestAsHex(File)}.
992 *
993 * @param name the name of the {@link MessageDigest} to use
994 * @see #getDigest(String)
995 * @throws IllegalArgumentException
996 * when a {@link NoSuchAlgorithmException} is caught.
997 * @since 1.11
998 */
999 public DigestUtils(final String name) {
1000 this(getDigest(name));
1001 }
1002
1003 /**
1004 * Returns the message digest instance.
1005 * @return the message digest instance
1006 * @since 1.11
1007 */
1008 public MessageDigest getMessageDigest() {
1009 return messageDigest;
1010 }
1011
1012 /**
1013 * Reads through a byte array and returns the digest for the data.
1014 *
1015 * @param data
1016 * Data to digest
1017 * @return the digest
1018 * @since 1.11
1019 */
1020 public byte[] digest(final byte[] data) {
1021 return updateDigest(messageDigest, data).digest();
1022 }
1023
1024 /**
1025 * Reads through a byte array and returns the digest for the data.
1026 *
1027 * @param data
1028 * Data to digest treated as UTF-8 string
1029 * @return the digest
1030 * @since 1.11
1031 */
1032 public byte[] digest(final String data) {
1033 return updateDigest(messageDigest, data).digest();
1034 }
1035
1036 /**
1037 * Reads through a ByteBuffer and returns the digest for the data
1038 *
1039 * @param data
1040 * Data to digest
1041 * @return the digest
1042 *
1043 * @since 1.11
1044 */
1045 public byte[] digest(final ByteBuffer data) {
1046 return updateDigest(messageDigest, data).digest();
1047 }
1048
1049 /**
1050 * Reads through a File and returns the digest for the data
1051 *
1052 * @param data
1053 * Data to digest
1054 * @return the digest
1055 * @throws IOException
1056 * On error reading from the stream
1057 * @since 1.11
1058 */
1059 public byte[] digest(final File data) throws IOException {
1060 return updateDigest(messageDigest, data).digest();
1061 }
1062
1063 /**
1064 * Reads through an InputStream and returns the digest for the data
1065 *
1066 * @param data
1067 * Data to digest
1068 * @return the digest
1069 * @throws IOException
1070 * On error reading from the stream
1071 * @since 1.11
1072 */
1073 public byte[] digest(final InputStream data) throws IOException {
1074 return updateDigest(messageDigest, data).digest();
1075 }
1076
1077 /**
1078 * Reads through a byte array and returns the digest for the data.
1079 *
1080 * @param data
1081 * Data to digest
1082 * @return the digest as a hex string
1083 * @since 1.11
1084 */
1085 public String digestAsHex(final byte[] data) {
1086 return Hex.encodeHexString(digest(data));
1087 }
1088
1089 /**
1090 * Reads through a byte array and returns the digest for the data.
1091 *
1092 * @param data
1093 * Data to digest treated as UTF-8 string
1094 * @return the digest as a hex string
1095 * @since 1.11
1096 */
1097 public String digestAsHex(final String data) {
1098 return Hex.encodeHexString(digest(data));
1099 }
1100
1101 /**
1102 * Reads through a ByteBuffer and returns the digest for the data
1103 *
1104 * @param data
1105 * Data to digest
1106 * @return the digest as a hex string
1107 *
1108 * @since 1.11
1109 */
1110 public String digestAsHex(final ByteBuffer data) {
1111 return Hex.encodeHexString(digest(data));
1112 }
1113
1114 /**
1115 * Reads through a File and returns the digest for the data
1116 *
1117 * @param data
1118 * Data to digest
1119 * @return the digest as a hex string
1120 * @throws IOException
1121 * On error reading from the stream
1122 * @since 1.11
1123 */
1124 public String digestAsHex(final File data) throws IOException {
1125 return Hex.encodeHexString(digest(data));
1126 }
1127
1128 /**
1129 * Reads through an InputStream and returns the digest for the data
1130 *
1131 * @param data
1132 * Data to digest
1133 * @return the digest as a hex string
1134 * @throws IOException
1135 * On error reading from the stream
1136 * @since 1.11
1137 */
1138 public String digestAsHex(final InputStream data) throws IOException {
1139 return Hex.encodeHexString(digest(data));
1140 }
1141
1142 }