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 simplifiy common {@link java.security.MessageDigest} tasks. This class is thread safe. 030 * 031 * @author Apache Software Foundation 032 * @version $Id: DigestUtils.java 801391 2009-08-05 19:55:54Z ggregory $ 033 */ 034 public class DigestUtils { 035 036 private static final int STREAM_BUFFER_LENGTH = 1024; 037 038 /** 039 * Read through an InputStream and returns the digest for the data 040 * 041 * @param digest 042 * The MessageDigest to use (e.g. MD5) 043 * @param data 044 * Data to digest 045 * @return MD5 digest 046 * @throws IOException 047 * On error reading from the stream 048 */ 049 private static byte[] digest(MessageDigest digest, InputStream data) throws IOException { 050 byte[] buffer = new byte[STREAM_BUFFER_LENGTH]; 051 int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH); 052 053 while (read > -1) { 054 digest.update(buffer, 0, read); 055 read = data.read(buffer, 0, STREAM_BUFFER_LENGTH); 056 } 057 058 return digest.digest(); 059 } 060 061 /** 062 * Calls {@link StringUtils#getBytesUtf8(String)} 063 * 064 * @param string 065 * the String to encode 066 * @return encoded bytes 067 */ 068 private static byte[] getBytesUtf8(String data) { 069 return StringUtils.getBytesUtf8(data); 070 } 071 072 /** 073 * Returns a <code>MessageDigest</code> for the given <code>algorithm</code>. 074 * 075 * @param algorithm 076 * the name of the algorithm requested. See <a 077 * href="http://java.sun.com/j2se/1.3/docs/guide/security/CryptoSpec.html#AppA">Appendix A in the Java 078 * Cryptography Architecture API Specification & Reference</a> for information about standard algorithm 079 * names. 080 * @return An MD5 digest instance. 081 * @see MessageDigest#getInstance(String) 082 * @throws RuntimeException 083 * when a {@link java.security.NoSuchAlgorithmException} is caught. 084 */ 085 static MessageDigest getDigest(String algorithm) { 086 try { 087 return MessageDigest.getInstance(algorithm); 088 } catch (NoSuchAlgorithmException e) { 089 throw new RuntimeException(e.getMessage()); 090 } 091 } 092 093 /** 094 * Returns an MD5 MessageDigest. 095 * 096 * @return An MD5 digest instance. 097 * @throws RuntimeException 098 * when a {@link java.security.NoSuchAlgorithmException} is caught. 099 */ 100 private static MessageDigest getMd5Digest() { 101 return getDigest("MD5"); 102 } 103 104 /** 105 * Returns an SHA-256 digest. 106 * <p> 107 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 108 * </p> 109 * 110 * @return An SHA-256 digest instance. 111 * @throws RuntimeException 112 * when a {@link java.security.NoSuchAlgorithmException} is caught. 113 */ 114 private static MessageDigest getSha256Digest() { 115 return getDigest("SHA-256"); 116 } 117 118 /** 119 * Returns an SHA-384 digest. 120 * <p> 121 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 122 * </p> 123 * 124 * @return An SHA-384 digest instance. 125 * @throws RuntimeException 126 * when a {@link java.security.NoSuchAlgorithmException} is caught. 127 */ 128 private static MessageDigest getSha384Digest() { 129 return getDigest("SHA-384"); 130 } 131 132 /** 133 * Returns an SHA-512 digest. 134 * <p> 135 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 136 * </p> 137 * 138 * @return An SHA-512 digest instance. 139 * @throws RuntimeException 140 * when a {@link java.security.NoSuchAlgorithmException} is caught. 141 */ 142 private static MessageDigest getSha512Digest() { 143 return getDigest("SHA-512"); 144 } 145 146 /** 147 * Returns an SHA-1 digest. 148 * 149 * @return An SHA-1 digest instance. 150 * @throws RuntimeException 151 * when a {@link java.security.NoSuchAlgorithmException} is caught. 152 */ 153 private static MessageDigest getShaDigest() { 154 return getDigest("SHA"); 155 } 156 157 /** 158 * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>. 159 * 160 * @param data 161 * Data to digest 162 * @return MD5 digest 163 */ 164 public static byte[] md5(byte[] data) { 165 return getMd5Digest().digest(data); 166 } 167 168 /** 169 * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>. 170 * 171 * @param data 172 * Data to digest 173 * @return MD5 digest 174 * @throws IOException 175 * On error reading from the stream 176 * @since 1.4 177 */ 178 public static byte[] md5(InputStream data) throws IOException { 179 return digest(getMd5Digest(), data); 180 } 181 182 /** 183 * Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>. 184 * 185 * @param data 186 * Data to digest 187 * @return MD5 digest 188 */ 189 public static byte[] md5(String data) { 190 return md5(getBytesUtf8(data)); 191 } 192 193 /** 194 * Calculates the MD5 digest and returns the value as a 32 character hex string. 195 * 196 * @param data 197 * Data to digest 198 * @return MD5 digest as a hex string 199 */ 200 public static String md5Hex(byte[] data) { 201 return Hex.encodeHexString(md5(data)); 202 } 203 204 /** 205 * Calculates the MD5 digest and returns the value as a 32 character hex string. 206 * 207 * @param data 208 * Data to digest 209 * @return MD5 digest as a hex string 210 * @throws IOException 211 * On error reading from the stream 212 * @since 1.4 213 */ 214 public static String md5Hex(InputStream data) throws IOException { 215 return Hex.encodeHexString(md5(data)); 216 } 217 218 /** 219 * Calculates the MD5 digest and returns the value as a 32 character hex string. 220 * 221 * @param data 222 * Data to digest 223 * @return MD5 digest as a hex string 224 */ 225 public static String md5Hex(String data) { 226 return Hex.encodeHexString(md5(data)); 227 } 228 229 /** 230 * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>. 231 * 232 * @param data 233 * Data to digest 234 * @return SHA-1 digest 235 */ 236 public static byte[] sha(byte[] data) { 237 return getShaDigest().digest(data); 238 } 239 240 /** 241 * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>. 242 * 243 * @param data 244 * Data to digest 245 * @return SHA-1 digest 246 * @throws IOException 247 * On error reading from the stream 248 * @since 1.4 249 */ 250 public static byte[] sha(InputStream data) throws IOException { 251 return digest(getShaDigest(), data); 252 } 253 254 /** 255 * Calculates the SHA-1 digest and returns the value as a <code>byte[]</code>. 256 * 257 * @param data 258 * Data to digest 259 * @return SHA-1 digest 260 */ 261 public static byte[] sha(String data) { 262 return sha(getBytesUtf8(data)); 263 } 264 265 /** 266 * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>. 267 * <p> 268 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 269 * </p> 270 * 271 * @param data 272 * Data to digest 273 * @return SHA-256 digest 274 * @since 1.4 275 */ 276 public static byte[] sha256(byte[] data) { 277 return getSha256Digest().digest(data); 278 } 279 280 /** 281 * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>. 282 * <p> 283 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 284 * </p> 285 * 286 * @param data 287 * Data to digest 288 * @return SHA-256 digest 289 * @throws IOException 290 * On error reading from the stream 291 * @since 1.4 292 */ 293 public static byte[] sha256(InputStream data) throws IOException { 294 return digest(getSha256Digest(), data); 295 } 296 297 /** 298 * Calculates the SHA-256 digest and returns the value as a <code>byte[]</code>. 299 * <p> 300 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 301 * </p> 302 * 303 * @param data 304 * Data to digest 305 * @return SHA-256 digest 306 * @since 1.4 307 */ 308 public static byte[] sha256(String data) { 309 return sha256(getBytesUtf8(data)); 310 } 311 312 /** 313 * Calculates the SHA-256 digest and returns the value as a hex string. 314 * <p> 315 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 316 * </p> 317 * 318 * @param data 319 * Data to digest 320 * @return SHA-256 digest as a hex string 321 * @since 1.4 322 */ 323 public static String sha256Hex(byte[] data) { 324 return Hex.encodeHexString(sha256(data)); 325 } 326 327 /** 328 * Calculates the SHA-256 digest and returns the value as a hex string. 329 * <p> 330 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 331 * </p> 332 * 333 * @param data 334 * Data to digest 335 * @return SHA-256 digest as a hex string 336 * @throws IOException 337 * On error reading from the stream 338 * @since 1.4 339 */ 340 public static String sha256Hex(InputStream data) throws IOException { 341 return Hex.encodeHexString(sha256(data)); 342 } 343 344 /** 345 * Calculates the SHA-256 digest and returns the value as a hex string. 346 * <p> 347 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 348 * </p> 349 * 350 * @param data 351 * Data to digest 352 * @return SHA-256 digest as a hex string 353 * @since 1.4 354 */ 355 public static String sha256Hex(String data) { 356 return Hex.encodeHexString(sha256(data)); 357 } 358 359 /** 360 * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>. 361 * <p> 362 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 363 * </p> 364 * 365 * @param data 366 * Data to digest 367 * @return SHA-384 digest 368 * @since 1.4 369 */ 370 public static byte[] sha384(byte[] data) { 371 return getSha384Digest().digest(data); 372 } 373 374 /** 375 * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>. 376 * <p> 377 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 378 * </p> 379 * 380 * @param data 381 * Data to digest 382 * @return SHA-384 digest 383 * @throws IOException 384 * On error reading from the stream 385 * @since 1.4 386 */ 387 public static byte[] sha384(InputStream data) throws IOException { 388 return digest(getSha384Digest(), data); 389 } 390 391 /** 392 * Calculates the SHA-384 digest and returns the value as a <code>byte[]</code>. 393 * <p> 394 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 395 * </p> 396 * 397 * @param data 398 * Data to digest 399 * @return SHA-384 digest 400 * @since 1.4 401 */ 402 public static byte[] sha384(String data) { 403 return sha384(getBytesUtf8(data)); 404 } 405 406 /** 407 * Calculates the SHA-384 digest and returns the value as a hex string. 408 * <p> 409 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 410 * </p> 411 * 412 * @param data 413 * Data to digest 414 * @return SHA-384 digest as a hex string 415 * @since 1.4 416 */ 417 public static String sha384Hex(byte[] data) { 418 return Hex.encodeHexString(sha384(data)); 419 } 420 421 /** 422 * Calculates the SHA-384 digest and returns the value as a hex string. 423 * <p> 424 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 425 * </p> 426 * 427 * @param data 428 * Data to digest 429 * @return SHA-384 digest as a hex string 430 * @throws IOException 431 * On error reading from the stream 432 * @since 1.4 433 */ 434 public static String sha384Hex(InputStream data) throws IOException { 435 return Hex.encodeHexString(sha384(data)); 436 } 437 438 /** 439 * Calculates the SHA-384 digest and returns the value as a hex string. 440 * <p> 441 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 442 * </p> 443 * 444 * @param data 445 * Data to digest 446 * @return SHA-384 digest as a hex string 447 * @since 1.4 448 */ 449 public static String sha384Hex(String data) { 450 return Hex.encodeHexString(sha384(data)); 451 } 452 453 /** 454 * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>. 455 * <p> 456 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 457 * </p> 458 * 459 * @param data 460 * Data to digest 461 * @return SHA-512 digest 462 * @since 1.4 463 */ 464 public static byte[] sha512(byte[] data) { 465 return getSha512Digest().digest(data); 466 } 467 468 /** 469 * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>. 470 * <p> 471 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 472 * </p> 473 * 474 * @param data 475 * Data to digest 476 * @return SHA-512 digest 477 * @throws IOException 478 * On error reading from the stream 479 * @since 1.4 480 */ 481 public static byte[] sha512(InputStream data) throws IOException { 482 return digest(getSha512Digest(), data); 483 } 484 485 /** 486 * Calculates the SHA-512 digest and returns the value as a <code>byte[]</code>. 487 * <p> 488 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 489 * </p> 490 * 491 * @param data 492 * Data to digest 493 * @return SHA-512 digest 494 * @since 1.4 495 */ 496 public static byte[] sha512(String data) { 497 return sha512(getBytesUtf8(data)); 498 } 499 500 /** 501 * Calculates the SHA-512 digest and returns the value as a hex string. 502 * <p> 503 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 504 * </p> 505 * 506 * @param data 507 * Data to digest 508 * @return SHA-512 digest as a hex string 509 * @since 1.4 510 */ 511 public static String sha512Hex(byte[] data) { 512 return Hex.encodeHexString(sha512(data)); 513 } 514 515 /** 516 * Calculates the SHA-512 digest and returns the value as a hex string. 517 * <p> 518 * Throws a <code>RuntimeException</code> on JRE versions prior to 1.4.0. 519 * </p> 520 * 521 * @param data 522 * Data to digest 523 * @return SHA-512 digest as a hex string 524 * @throws IOException 525 * On error reading from the stream 526 * @since 1.4 527 */ 528 public static String sha512Hex(InputStream data) throws IOException { 529 return Hex.encodeHexString(sha512(data)); 530 } 531 532 /** 533 * Calculates the SHA-512 digest and returns the value as a hex string. 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-512 digest as a hex string 541 * @since 1.4 542 */ 543 public static String sha512Hex(String data) { 544 return Hex.encodeHexString(sha512(data)); 545 } 546 547 /** 548 * Calculates the SHA-1 digest and returns the value as a hex string. 549 * 550 * @param data 551 * Data to digest 552 * @return SHA-1 digest as a hex string 553 */ 554 public static String shaHex(byte[] data) { 555 return Hex.encodeHexString(sha(data)); 556 } 557 558 /** 559 * Calculates the SHA-1 digest and returns the value as a hex string. 560 * 561 * @param data 562 * Data to digest 563 * @return SHA-1 digest as a hex string 564 * @throws IOException 565 * On error reading from the stream 566 * @since 1.4 567 */ 568 public static String shaHex(InputStream data) throws IOException { 569 return Hex.encodeHexString(sha(data)); 570 } 571 572 /** 573 * Calculates the SHA-1 digest and returns the value as a hex string. 574 * 575 * @param data 576 * Data to digest 577 * @return SHA-1 digest as a hex string 578 */ 579 public static String shaHex(String data) { 580 return Hex.encodeHexString(sha(data)); 581 } 582 }