001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.codec.digest; 019 020 import java.io.IOException; 021 import java.io.InputStream; 022 import java.security.MessageDigest; 023 import java.security.NoSuchAlgorithmException; 024 025 import org.apache.commons.codec.binary.Hex; 026 import org.apache.commons.codec.binary.StringUtils; 027 028 /** 029 * Operations to simplify common {@link java.security.MessageDigest} tasks. This class is thread safe. 030 * 031 * @version $Id: DigestUtils.html 889935 2013-12-11 05:05:13Z ggregory $ 032 */ 033 public class DigestUtils { 034 035 private static final int STREAM_BUFFER_LENGTH = 1024; 036 037 /** 038 * Read through an InputStream and returns the digest for the data 039 * 040 * @param digest 041 * The MessageDigest to use (e.g. MD5) 042 * @param data 043 * Data to digest 044 * @return MD5 digest 045 * @throws IOException 046 * On error reading from the stream 047 */ 048 private static byte[] digest(MessageDigest digest, InputStream data) throws IOException { 049 byte[] buffer = new byte[STREAM_BUFFER_LENGTH]; 050 int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH); 051 052 while (read > -1) { 053 digest.update(buffer, 0, read); 054 read = data.read(buffer, 0, STREAM_BUFFER_LENGTH); 055 } 056 057 return digest.digest(); 058 } 059 060 /** 061 * Calls {@link StringUtils#getBytesUtf8(String)} 062 * 063 * @param data 064 * the String to encode 065 * @return encoded bytes 066 */ 067 private static byte[] getBytesUtf8(String data) { 068 return StringUtils.getBytesUtf8(data); 069 } 070 071 /** 072 * Returns a <code>MessageDigest</code> for the given <code>algorithm</code>. 073 * 074 * @param algorithm 075 * the name of the algorithm requested. See <a 076 * href="http://java.sun.com/j2se/1.3/docs/guide/security/CryptoSpec.html#AppA">Appendix A in the Java 077 * Cryptography Architecture API Specification & Reference</a> for information about standard algorithm 078 * names. 079 * @return An MD5 digest instance. 080 * @see MessageDigest#getInstance(String) 081 * @throws IllegalArgumentException 082 * when a {@link NoSuchAlgorithmException} is caught. 083 */ 084 public static MessageDigest getDigest(String algorithm) { 085 try { 086 return MessageDigest.getInstance(algorithm); 087 } catch (NoSuchAlgorithmException e) { 088 throw new IllegalArgumentException(e); 089 } 090 } 091 092 /** 093 * Returns an MD2 MessageDigest. 094 * 095 * @return An MD2 digest instance. 096 * @throws IllegalArgumentException 097 * when a {@link NoSuchAlgorithmException} is caught, which should never happen because MD2 is a 098 * built-in algorithm 099 * @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 }