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 018package org.apache.commons.codec.digest; 019 020import java.io.BufferedInputStream; 021import java.io.File; 022import java.io.FileInputStream; 023import java.io.IOException; 024import java.io.InputStream; 025import java.nio.ByteBuffer; 026import java.security.InvalidKeyException; 027import java.security.Key; 028import java.security.NoSuchAlgorithmException; 029 030import javax.crypto.Mac; 031import javax.crypto.spec.SecretKeySpec; 032 033import org.apache.commons.codec.binary.Hex; 034import org.apache.commons.codec.binary.StringUtils; 035 036/** 037 * Simplifies common {@link javax.crypto.Mac} tasks. This class is immutable and thread-safe. 038 * However the Mac may not be. 039 * <p> 040 * <strong>Note: Not all JCE implementations support all algorithms. If not supported, an IllegalArgumentException is 041 * thrown.</strong> 042 * <p> 043 * Sample usage: 044 * <pre> 045 * import static HmacAlgorithms.*; 046 * byte[] key = {1,2,3,4}; // don't use this actual key! 047 * String valueToDigest = "The quick brown fox jumps over the lazy dog"; 048 * byte[] hmac = new HmacUtils(HMAC_SHA_224, key).hmac(valueToDigest); 049 * // Mac re-use 050 * HmacUtils hm1 = new HmacUtils("HmacAlgoName", key); // use a valid name here! 051 * String hexPom = hm1.hmacHex(new File("pom.xml")); 052 * String hexNot = hm1.hmacHex(new File("NOTICE.txt")); 053 * </pre> 054 * @since 1.10 055 */ 056public final class HmacUtils { 057 058 private static final int STREAM_BUFFER_LENGTH = 1024; 059 060 /** 061 * Returns whether this algorithm is available 062 * 063 *@param name the name to check 064 * @return whether this algorithm is available 065 * @since 1.11 066 */ 067 public static boolean isAvailable(final String name) { 068 try { 069 Mac.getInstance(name); 070 return true; 071 } catch (final NoSuchAlgorithmException e) { 072 return false; 073 } 074 } 075 076 /** 077 * Returns whether this algorithm is available 078 * 079 *@param name the name to check 080 * @return whether this algorithm is available 081 * @since 1.11 082 */ 083 public static boolean isAvailable(final HmacAlgorithms name) { 084 try { 085 Mac.getInstance(name.getName()); 086 return true; 087 } catch (final NoSuchAlgorithmException e) { 088 return false; 089 } 090 } 091 092 /** 093 * Returns an initialized <code>Mac</code> for the HmacMD5 algorithm. 094 * <p> 095 * Every implementation of the Java platform is required to support this standard Mac algorithm. 096 * </p> 097 * 098 * @param key 099 * They key for the keyed digest (must not be null) 100 * @return A Mac instance initialized with the given key. 101 * @see Mac#getInstance(String) 102 * @see Mac#init(Key) 103 * @throws IllegalArgumentException 104 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 105 * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_MD5, byte[])} 106 */ 107 @Deprecated 108 public static Mac getHmacMd5(final byte[] key) { 109 return getInitializedMac(HmacAlgorithms.HMAC_MD5, key); 110 } 111 112 /** 113 * Returns an initialized <code>Mac</code> for the HmacSHA1 algorithm. 114 * <p> 115 * Every implementation of the Java platform is required to support this standard Mac algorithm. 116 * </p> 117 * 118 * @param key 119 * They key for the keyed digest (must not be null) 120 * @return A Mac instance initialized with the given key. 121 * @see Mac#getInstance(String) 122 * @see Mac#init(Key) 123 * @throws IllegalArgumentException 124 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 125 * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_1, byte[])} 126 */ 127 @Deprecated 128 public static Mac getHmacSha1(final byte[] key) { 129 return getInitializedMac(HmacAlgorithms.HMAC_SHA_1, key); 130 } 131 132 /** 133 * Returns an initialized <code>Mac</code> for the HmacSHA256 algorithm. 134 * <p> 135 * Every implementation of the Java platform is required to support this standard Mac algorithm. 136 * </p> 137 * 138 * @param key 139 * They key for the keyed digest (must not be null) 140 * @return A Mac instance initialized with the given key. 141 * @see Mac#getInstance(String) 142 * @see Mac#init(Key) 143 * @throws IllegalArgumentException 144 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 145 * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_256, byte[])} 146 */ 147 @Deprecated 148 public static Mac getHmacSha256(final byte[] key) { 149 return getInitializedMac(HmacAlgorithms.HMAC_SHA_256, key); 150 } 151 152 /** 153 * Returns an initialized <code>Mac</code> for the HmacSHA384 algorithm. 154 * <p> 155 * Every implementation of the Java platform is <em>not</em> required to support this Mac algorithm. 156 * </p> 157 * 158 * @param key 159 * They key for the keyed digest (must not be null) 160 * @return A Mac instance initialized with the given key. 161 * @see Mac#getInstance(String) 162 * @see Mac#init(Key) 163 * @throws IllegalArgumentException 164 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 165 * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_384, byte[])} 166 */ 167 @Deprecated 168 public static Mac getHmacSha384(final byte[] key) { 169 return getInitializedMac(HmacAlgorithms.HMAC_SHA_384, key); 170 } 171 172 /** 173 * Returns an initialized <code>Mac</code> for the HmacSHA512 algorithm. 174 * <p> 175 * Every implementation of the Java platform is <em>not</em> required to support this Mac algorithm. 176 * </p> 177 * 178 * @param key 179 * They key for the keyed digest (must not be null) 180 * @return A Mac instance initialized with the given key. 181 * @see Mac#getInstance(String) 182 * @see Mac#init(Key) 183 * @throws IllegalArgumentException 184 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 185 * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_512, byte[])} 186 */ 187 @Deprecated 188 public static Mac getHmacSha512(final byte[] key) { 189 return getInitializedMac(HmacAlgorithms.HMAC_SHA_512, key); 190 } 191 192 /** 193 * Returns an initialized <code>Mac</code> for the given <code>algorithm</code>. 194 * 195 * @param algorithm 196 * the name of the algorithm requested. See 197 * <a href= "http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA" 198 * >Appendix A in the Java Cryptography Architecture Reference Guide</a> for information about standard 199 * algorithm names. 200 * @param key 201 * They key for the keyed digest (must not be null) 202 * @return A Mac instance initialized with the given key. 203 * @see Mac#getInstance(String) 204 * @see Mac#init(Key) 205 * @throws IllegalArgumentException 206 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 207 */ 208 public static Mac getInitializedMac(final HmacAlgorithms algorithm, final byte[] key) { 209 return getInitializedMac(algorithm.getName(), key); 210 } 211 212 /** 213 * Returns an initialized <code>Mac</code> for the given <code>algorithm</code>. 214 * 215 * @param algorithm 216 * the name of the algorithm requested. See 217 * <a href= "http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA" 218 * >Appendix A in the Java Cryptography Architecture Reference Guide</a> for information about standard 219 * algorithm names. 220 * @param key 221 * They key for the keyed digest (must not be null) 222 * @return A Mac instance initialized with the given key. 223 * @see Mac#getInstance(String) 224 * @see Mac#init(Key) 225 * @throws IllegalArgumentException 226 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 227 */ 228 public static Mac getInitializedMac(final String algorithm, final byte[] key) { 229 230 if (key == null) { 231 throw new IllegalArgumentException("Null key"); 232 } 233 234 try { 235 final SecretKeySpec keySpec = new SecretKeySpec(key, algorithm); 236 final Mac mac = Mac.getInstance(algorithm); 237 mac.init(keySpec); 238 return mac; 239 } catch (final NoSuchAlgorithmException e) { 240 throw new IllegalArgumentException(e); 241 } catch (final InvalidKeyException e) { 242 throw new IllegalArgumentException(e); 243 } 244 } 245 246 // hmacMd5 247 248 /** 249 * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value. 250 * 251 * @param key 252 * They key for the keyed digest (must not be null) 253 * @param valueToDigest 254 * The value (data) which should to digest (maybe empty or null) 255 * @return HmacMD5 MAC for the given key and value 256 * @throws IllegalArgumentException 257 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 258 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmac(byte[])} 259 */ 260 @Deprecated 261 public static byte[] hmacMd5(final byte[] key, final byte[] valueToDigest) { 262 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmac(valueToDigest); 263 } 264 265 /** 266 * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value. 267 * 268 * @param key 269 * They key for the keyed digest (must not be null) 270 * @param valueToDigest 271 * The value (data) which should to digest 272 * <p> 273 * The InputStream must not be null and will not be closed 274 * </p> 275 * @return HmacMD5 MAC for the given key and value 276 * @throws IOException 277 * If an I/O error occurs. 278 * @throws IllegalArgumentException 279 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 280 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmac(InputStream)} 281 */ 282 @Deprecated 283 public static byte[] hmacMd5(final byte[] key, final InputStream valueToDigest) throws IOException { 284 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmac(valueToDigest); 285 } 286 287 /** 288 * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value. 289 * 290 * @param key 291 * They key for the keyed digest (must not be null) 292 * @param valueToDigest 293 * The value (data) which should to digest (maybe empty or null) 294 * @return HmacMD5 MAC for the given key and value 295 * @throws IllegalArgumentException 296 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 297 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, String).hmac(String)} 298 */ 299 @Deprecated 300 public static byte[] hmacMd5(final String key, final String valueToDigest) { 301 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmac(valueToDigest); 302 } 303 304 /** 305 * Returns a HmacMD5 Message Authentication Code (MAC) as a hex string (lowercase) for the given key and value. 306 * 307 * @param key 308 * They key for the keyed digest (must not be null) 309 * @param valueToDigest 310 * The value (data) which should to digest (maybe empty or null) 311 * @return HmacMD5 MAC for the given key and value as a hex string (lowercase) 312 * @throws IllegalArgumentException 313 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 314 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmacHex(byte[])} 315 */ 316 @Deprecated 317 public static String hmacMd5Hex(final byte[] key, final byte[] valueToDigest) { 318 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(valueToDigest); 319 } 320 321 /** 322 * Returns a HmacMD5 Message Authentication Code (MAC) as a hex string (lowercase) for the given key and value. 323 * 324 * @param key 325 * They key for the keyed digest (must not be null) 326 * @param valueToDigest 327 * The value (data) which should to digest 328 * <p> 329 * The InputStream must not be null and will not be closed 330 * </p> 331 * @return HmacMD5 MAC for the given key and value as a hex string (lowercase) 332 * @throws IOException 333 * If an I/O error occurs. 334 * @throws IllegalArgumentException 335 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 336 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmacHex(InputStream)} 337 */ 338 @Deprecated 339 public static String hmacMd5Hex(final byte[] key, final InputStream valueToDigest) throws IOException { 340 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(valueToDigest); 341 } 342 343 /** 344 * Returns a HmacMD5 Message Authentication Code (MAC) as a hex string (lowercase) for the given key and value. 345 * 346 * @param key 347 * They key for the keyed digest (must not be null) 348 * @param valueToDigest 349 * The value (data) which should to digest (maybe empty or null) 350 * @return HmacMD5 MAC for the given key and value as a hex string (lowercase) 351 * @throws IllegalArgumentException 352 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 353 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, String).hmacHex(String)} 354 */ 355 @Deprecated 356 public static String hmacMd5Hex(final String key, final String valueToDigest) { 357 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(valueToDigest); 358 } 359 360 // hmacSha1 361 362 /** 363 * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value. 364 * 365 * @param key 366 * They key for the keyed digest (must not be null) 367 * @param valueToDigest 368 * The value (data) which should to digest (maybe empty or null) 369 * @return HmacSHA1 MAC for the given key and value 370 * @throws IllegalArgumentException 371 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 372 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmac(byte[])} 373 */ 374 @Deprecated 375 public static byte[] hmacSha1(final byte[] key, final byte[] valueToDigest) { 376 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmac(valueToDigest); 377 } 378 379 /** 380 * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value. 381 * 382 * @param key 383 * They key for the keyed digest (must not be null) 384 * @param valueToDigest 385 * The value (data) which should to digest 386 * <p> 387 * The InputStream must not be null and will not be closed 388 * </p> 389 * @return HmacSHA1 MAC for the given key and value 390 * @throws IOException 391 * If an I/O error occurs. 392 * @throws IllegalArgumentException 393 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 394 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmac(InputStream)} 395 */ 396 @Deprecated 397 public static byte[] hmacSha1(final byte[] key, final InputStream valueToDigest) throws IOException { 398 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmac(valueToDigest); 399 } 400 401 /** 402 * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value. 403 * 404 * @param key 405 * They key for the keyed digest (must not be null) 406 * @param valueToDigest 407 * The value (data) which should to digest (maybe empty or null) 408 * @return HmacSHA1 MAC for the given key and value 409 * @throws IllegalArgumentException 410 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 411 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, String).hmac(String)} 412 */ 413 @Deprecated 414 public static byte[] hmacSha1(final String key, final String valueToDigest) { 415 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmac(valueToDigest); 416 } 417 418 /** 419 * Returns a HmacSHA1 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 420 * 421 * @param key 422 * They key for the keyed digest (must not be null) 423 * @param valueToDigest 424 * The value (data) which should to digest (maybe empty or null) 425 * @return HmacSHA1 MAC for the given key and value as hex string (lowercase) 426 * @throws IllegalArgumentException 427 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 428 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmacHex(byte[])} 429 */ 430 @Deprecated 431 public static String hmacSha1Hex(final byte[] key, final byte[] valueToDigest) { 432 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(valueToDigest); 433 } 434 435 /** 436 * Returns a HmacSHA1 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 437 * 438 * @param key 439 * They key for the keyed digest (must not be null) 440 * @param valueToDigest 441 * The value (data) which should to digest 442 * <p> 443 * The InputStream must not be null and will not be closed 444 * </p> 445 * @return HmacSHA1 MAC for the given key and value as hex string (lowercase) 446 * @throws IOException 447 * If an I/O error occurs. 448 * @throws IllegalArgumentException 449 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 450 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmacHex(InputStream)} 451 */ 452 @Deprecated 453 public static String hmacSha1Hex(final byte[] key, final InputStream valueToDigest) throws IOException { 454 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(valueToDigest); 455 } 456 457 /** 458 * Returns a HmacSHA1 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 459 * 460 * @param key 461 * They key for the keyed digest (must not be null) 462 * @param valueToDigest 463 * The value (data) which should to digest (maybe empty or null) 464 * @return HmacSHA1 MAC for the given key and value as hex string (lowercase) 465 * @throws IllegalArgumentException 466 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 467 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, String).hmacHex(String)} 468 */ 469 @Deprecated 470 public static String hmacSha1Hex(final String key, final String valueToDigest) { 471 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(valueToDigest); 472 } 473 474 // hmacSha256 475 476 /** 477 * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value. 478 * 479 * @param key 480 * They key for the keyed digest (must not be null) 481 * @param valueToDigest 482 * The value (data) which should to digest (maybe empty or null) 483 * @return HmacSHA256 MAC for the given key and value 484 * @throws IllegalArgumentException 485 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 486 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmac(byte[])} 487 */ 488 @Deprecated 489 public static byte[] hmacSha256(final byte[] key, final byte[] valueToDigest) { 490 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(valueToDigest); 491 } 492 493 /** 494 * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value. 495 * 496 * @param key 497 * They key for the keyed digest (must not be null) 498 * @param valueToDigest 499 * The value (data) which should to digest 500 * <p> 501 * The InputStream must not be null and will not be closed 502 * </p> 503 * @return HmacSHA256 MAC for the given key and value 504 * @throws IOException 505 * If an I/O error occurs. 506 * @throws IllegalArgumentException 507 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 508 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmac(InputStream)} 509 */ 510 @Deprecated 511 public static byte[] hmacSha256(final byte[] key, final InputStream valueToDigest) throws IOException { 512 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(valueToDigest); 513 } 514 515 /** 516 * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value. 517 * 518 * @param key 519 * They key for the keyed digest (must not be null) 520 * @param valueToDigest 521 * The value (data) which should to digest (maybe empty or null) 522 * @return HmacSHA256 MAC for the given key and value 523 * @throws IllegalArgumentException 524 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 525 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, String).hmac(String)} 526 */ 527 @Deprecated 528 public static byte[] hmacSha256(final String key, final String valueToDigest) { 529 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(valueToDigest); 530 } 531 532 /** 533 * Returns a HmacSHA256 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 534 * 535 * @param key 536 * They key for the keyed digest (must not be null) 537 * @param valueToDigest 538 * The value (data) which should to digest (maybe empty or null) 539 * @return HmacSHA256 MAC for the given key and value as hex string (lowercase) 540 * @throws IllegalArgumentException 541 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 542 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmacHex(byte[])} 543 */ 544 @Deprecated 545 public static String hmacSha256Hex(final byte[] key, final byte[] valueToDigest) { 546 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest); 547 } 548 549 /** 550 * Returns a HmacSHA256 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 551 * 552 * @param key 553 * They key for the keyed digest (must not be null) 554 * @param valueToDigest 555 * The value (data) which should to digest 556 * <p> 557 * The InputStream must not be null and will not be closed 558 * </p> 559 * @return HmacSHA256 MAC for the given key and value as hex string (lowercase) 560 * @throws IOException 561 * If an I/O error occurs. 562 * @throws IllegalArgumentException 563 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 564 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmacHex(InputStream)} 565 */ 566 @Deprecated 567 public static String hmacSha256Hex(final byte[] key, final InputStream valueToDigest) throws IOException { 568 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest); 569 } 570 571 /** 572 * Returns a HmacSHA256 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 573 * 574 * @param key 575 * They key for the keyed digest (must not be null) 576 * @param valueToDigest 577 * The value (data) which should to digest (maybe empty or null) 578 * @return HmacSHA256 MAC for the given key and value as hex string (lowercase) 579 * @throws IllegalArgumentException 580 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 581 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, String).hmacHex(String)} 582 */ 583 @Deprecated 584 public static String hmacSha256Hex(final String key, final String valueToDigest) { 585 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest); 586 } 587 588 // hmacSha384 589 590 /** 591 * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value. 592 * 593 * @param key 594 * They key for the keyed digest (must not be null) 595 * @param valueToDigest 596 * The value (data) which should to digest (maybe empty or null) 597 * @return HmacSHA384 MAC for the given key and value 598 * @throws IllegalArgumentException 599 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 600 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmac(byte[])} 601 */ 602 @Deprecated 603 public static byte[] hmacSha384(final byte[] key, final byte[] valueToDigest) { 604 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest); 605 } 606 607 /** 608 * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value. 609 * 610 * @param key 611 * They key for the keyed digest (must not be null) 612 * @param valueToDigest 613 * The value (data) which should to digest 614 * <p> 615 * The InputStream must not be null and will not be closed 616 * </p> 617 * @return HmacSHA384 MAC for the given key and value 618 * @throws IOException 619 * If an I/O error occurs. 620 * @throws IllegalArgumentException 621 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 622 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmac(InputStream)} 623 */ 624 @Deprecated 625 public static byte[] hmacSha384(final byte[] key, final InputStream valueToDigest) throws IOException { 626 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest); 627 } 628 629 /** 630 * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value. 631 * 632 * @param key 633 * They key for the keyed digest (must not be null) 634 * @param valueToDigest 635 * The value (data) which should to digest (maybe empty or null) 636 * @return HmacSHA384 MAC for the given key and value 637 * @throws IllegalArgumentException 638 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 639 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, String).hmac(String)} 640 */ 641 @Deprecated 642 public static byte[] hmacSha384(final String key, final String valueToDigest) { 643 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest); 644 } 645 646 /** 647 * Returns a HmacSHA384 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 648 * 649 * @param key 650 * They key for the keyed digest (must not be null) 651 * @param valueToDigest 652 * The value (data) which should to digest (maybe empty or null) 653 * @return HmacSHA384 MAC for the given key and value as hex string (lowercase) 654 * @throws IllegalArgumentException 655 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 656 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmacHex(byte[])} 657 */ 658 @Deprecated 659 public static String hmacSha384Hex(final byte[] key, final byte[] valueToDigest) { 660 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest); 661 } 662 663 /** 664 * Returns a HmacSHA384 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 665 * 666 * @param key 667 * They key for the keyed digest (must not be null) 668 * @param valueToDigest 669 * The value (data) which should to digest 670 * <p> 671 * The InputStream must not be null and will not be closed 672 * </p> 673 * @return HmacSHA384 MAC for the given key and value as hex string (lowercase) 674 * @throws IOException 675 * If an I/O error occurs. 676 * @throws IllegalArgumentException 677 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 678 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmacHex(InputStream)} 679 */ 680 @Deprecated 681 public static String hmacSha384Hex(final byte[] key, final InputStream valueToDigest) throws IOException { 682 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest); 683 } 684 685 /** 686 * Returns a HmacSHA384 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 687 * 688 * @param key 689 * They key for the keyed digest (must not be null) 690 * @param valueToDigest 691 * The value (data) which should to digest (maybe empty or null) 692 * @return HmacSHA384 MAC for the given key and value as hex string (lowercase) 693 * @throws IllegalArgumentException 694 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 695 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, String).hmacHex(String)} 696 */ 697 @Deprecated 698 public static String hmacSha384Hex(final String key, final String valueToDigest) { 699 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest); 700 } 701 702 // hmacSha512 703 704 /** 705 * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value. 706 * 707 * @param key 708 * They key for the keyed digest (must not be null) 709 * @param valueToDigest 710 * The value (data) which should to digest (maybe empty or null) 711 * @return HmacSHA512 MAC for the given key and value 712 * @throws IllegalArgumentException 713 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 714 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmac(byte[])} 715 */ 716 @Deprecated 717 public static byte[] hmacSha512(final byte[] key, final byte[] valueToDigest) { 718 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest); 719 } 720 721 /** 722 * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value. 723 * 724 * @param key 725 * They key for the keyed digest (must not be null) 726 * @param valueToDigest 727 * The value (data) which should to digest 728 * <p> 729 * The InputStream must not be null and will not be closed 730 * </p> 731 * @return HmacSHA512 MAC for the given key and value 732 * @throws IOException 733 * If an I/O error occurs. 734 * @throws IllegalArgumentException 735 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 736 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmac(InputStream)} 737 */ 738 @Deprecated 739 public static byte[] hmacSha512(final byte[] key, final InputStream valueToDigest) throws IOException { 740 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest); 741 } 742 743 /** 744 * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value. 745 * 746 * @param key 747 * They key for the keyed digest (must not be null) 748 * @param valueToDigest 749 * The value (data) which should to digest (maybe empty or null) 750 * @return HmacSHA512 MAC for the given key and value 751 * @throws IllegalArgumentException 752 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 753 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, String).hmac(String)} 754 */ 755 @Deprecated 756 public static byte[] hmacSha512(final String key, final String valueToDigest) { 757 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest); 758 } 759 760 /** 761 * Returns a HmacSHA512 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 762 * 763 * @param key 764 * They key for the keyed digest (must not be null) 765 * @param valueToDigest 766 * The value (data) which should to digest (maybe empty or null) 767 * @return HmacSHA512 MAC for the given key and value as hex string (lowercase) 768 * @throws IllegalArgumentException 769 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 770 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmacHex(byte[])} 771 */ 772 @Deprecated 773 public static String hmacSha512Hex(final byte[] key, final byte[] valueToDigest) { 774 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest); 775 } 776 777 /** 778 * Returns a HmacSHA512 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 779 * 780 * @param key 781 * They key for the keyed digest (must not be null) 782 * @param valueToDigest 783 * The value (data) which should to digest 784 * <p> 785 * The InputStream must not be null and will not be closed 786 * </p> 787 * @return HmacSHA512 MAC for the given key and value as hex string (lowercase) 788 * @throws IOException 789 * If an I/O error occurs. 790 * @throws IllegalArgumentException 791 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 792 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmacHex(InputStream)} 793 */ 794 @Deprecated 795 public static String hmacSha512Hex(final byte[] key, final InputStream valueToDigest) throws IOException { 796 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest); 797 } 798 799 /** 800 * Returns a HmacSHA512 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 801 * 802 * @param key 803 * They key for the keyed digest (must not be null) 804 * @param valueToDigest 805 * The value (data) which should to digest (maybe empty or null) 806 * @return HmacSHA512 MAC for the given key and value as hex string (lowercase) 807 * @throws IllegalArgumentException 808 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 809 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, String).hmacHex(String)} 810 */ 811 @Deprecated 812 public static String hmacSha512Hex(final String key, final String valueToDigest) { 813 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest); 814 } 815 816 // update 817 818 /** 819 * Resets and then updates the given {@link Mac} with the value. 820 * 821 * @param mac 822 * the initialized {@link Mac} to update 823 * @param valueToDigest 824 * the value to update the {@link Mac} with (maybe null or empty) 825 * @return the updated {@link Mac} 826 * @throws IllegalStateException 827 * if the Mac was not initialized 828 */ 829 public static Mac updateHmac(final Mac mac, final byte[] valueToDigest) { 830 mac.reset(); 831 mac.update(valueToDigest); 832 return mac; 833 } 834 835 /** 836 * Resets and then updates the given {@link Mac} with the value. 837 * 838 * @param mac 839 * the initialized {@link Mac} to update 840 * @param valueToDigest 841 * the value to update the {@link Mac} with 842 * <p> 843 * The InputStream must not be null and will not be closed 844 * </p> 845 * @return the updated {@link Mac} 846 * @throws IOException 847 * If an I/O error occurs. 848 * @throws IllegalStateException 849 * If the Mac was not initialized 850 */ 851 public static Mac updateHmac(final Mac mac, final InputStream valueToDigest) throws IOException { 852 mac.reset(); 853 final byte[] buffer = new byte[STREAM_BUFFER_LENGTH]; 854 int read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH); 855 856 while (read > -1) { 857 mac.update(buffer, 0, read); 858 read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH); 859 } 860 861 return mac; 862 } 863 864 /** 865 * Resets and then updates the given {@link Mac} with the value. 866 * 867 * @param mac 868 * the initialized {@link Mac} to update 869 * @param valueToDigest 870 * the value to update the {@link Mac} with (maybe null or empty) 871 * @return the updated {@link Mac} 872 * @throws IllegalStateException 873 * if the Mac was not initialized 874 */ 875 public static Mac updateHmac(final Mac mac, final String valueToDigest) { 876 mac.reset(); 877 mac.update(StringUtils.getBytesUtf8(valueToDigest)); 878 return mac; 879 } 880 881 /** 882 * Preserves binary compatibity only. 883 * As for previous versions does not provide useful behaviour 884 * @deprecated since 1.11; only useful to preserve binary compatibility 885 */ 886 @Deprecated 887 public HmacUtils() { 888 this(null); 889 } 890 891 private final Mac mac; 892 893 private HmacUtils(final Mac mac) { 894 this.mac = mac; 895 } 896 897 /** 898 * Creates an instance using the provided algorithm type. 899 * 900 * @param algorithm to use 901 * @param key the key to use 902 * @throws IllegalArgumentException 903 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 904 * @since 1.11 905 */ 906 public HmacUtils(final String algorithm, final byte[] key) { 907 this(getInitializedMac(algorithm, key)); 908 } 909 910 /** 911 * Creates an instance using the provided algorithm type. 912 * 913 * @param algorithm to use 914 * @param key the key to use 915 * @throws IllegalArgumentException 916 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 917 * @since 1.11 918 */ 919 public HmacUtils(final String algorithm, final String key) { 920 this(algorithm, StringUtils.getBytesUtf8(key)); 921 } 922 923 /** 924 * Creates an instance using the provided algorithm type. 925 * 926 * @param algorithm to use 927 * @param key the key to use 928 * @throws IllegalArgumentException 929 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 930 * @since 1.11 931 */ 932 public HmacUtils(final HmacAlgorithms algorithm, final String key) { 933 this(algorithm.getName(), StringUtils.getBytesUtf8(key)); 934 } 935 936 /** 937 * Creates an instance using the provided algorithm type. 938 * 939 * @param algorithm to use. 940 * @param key the key to use 941 * @throws IllegalArgumentException 942 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 943 * @since 1.11 944 */ 945 public HmacUtils(final HmacAlgorithms algorithm, final byte[] key) { 946 this(algorithm.getName(), key); 947 } 948 949 /** 950 * Returns the digest for the input data. 951 * 952 * @param valueToDigest the input to use 953 * @return the digest as a byte[] 954 * @since 1.11 955 */ 956 public byte[] hmac(final byte[] valueToDigest) { 957 return mac.doFinal(valueToDigest); 958 } 959 960 /** 961 * Returns the digest for the input data. 962 * 963 * @param valueToDigest the input to use 964 * @return the digest as a hex String 965 * @since 1.11 966 */ 967 public String hmacHex(final byte[] valueToDigest) { 968 return Hex.encodeHexString(hmac(valueToDigest)); 969 } 970 971 /** 972 * Returns the digest for the input data. 973 * 974 * @param valueToDigest the input to use, treated as UTF-8 975 * @return the digest as a byte[] 976 * @since 1.11 977 */ 978 public byte[] hmac(final String valueToDigest) { 979 return mac.doFinal(StringUtils.getBytesUtf8(valueToDigest)); 980 } 981 982 /** 983 * Returns the digest for the input data. 984 * 985 * @param valueToDigest the input to use, treated as UTF-8 986 * @return the digest as a hex String 987 * @since 1.11 988 */ 989 public String hmacHex(final String valueToDigest) { 990 return Hex.encodeHexString(hmac(valueToDigest)); 991 } 992 993 /** 994 * Returns the digest for the input data. 995 * 996 * @param valueToDigest the input to use 997 * @return the digest as a byte[] 998 * @since 1.11 999 */ 1000 public byte[] hmac(final ByteBuffer valueToDigest) { 1001 mac.update(valueToDigest); 1002 return mac.doFinal(); 1003 } 1004 1005 /** 1006 * Returns the digest for the input data. 1007 * 1008 * @param valueToDigest the input to use 1009 * @return the digest as a hex String 1010 * @since 1.11 1011 */ 1012 public String hmacHex(final ByteBuffer valueToDigest) { 1013 return Hex.encodeHexString(hmac(valueToDigest)); 1014 } 1015 1016 /** 1017 * Returns the digest for the stream. 1018 * 1019 * @param valueToDigest 1020 * the data to use 1021 * <p> 1022 * The InputStream must not be null and will not be closed 1023 * </p> 1024 * @return the digest 1025 * @throws IOException 1026 * If an I/O error occurs. 1027 * @since 1.11 1028 */ 1029 public byte[] hmac(final InputStream valueToDigest) throws IOException { 1030 final byte[] buffer = new byte[STREAM_BUFFER_LENGTH]; 1031 int read; 1032 1033 while ((read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH) ) > -1) { 1034 mac.update(buffer, 0, read); 1035 } 1036 return mac.doFinal(); 1037 } 1038 1039 /** 1040 * Returns the digest for the stream. 1041 * 1042 * @param valueToDigest 1043 * the data to use 1044 * <p> 1045 * The InputStream must not be null and will not be closed 1046 * </p> 1047 * @return the digest as a hex String 1048 * @throws IOException 1049 * If an I/O error occurs. 1050 * @since 1.11 1051 */ 1052 public String hmacHex(final InputStream valueToDigest) throws IOException { 1053 return Hex.encodeHexString(hmac(valueToDigest)); 1054 } 1055 1056 /** 1057 * Returns the digest for the file. 1058 * 1059 * @param valueToDigest the file to use 1060 * @return the digest 1061 * @throws IOException 1062 * If an I/O error occurs. 1063 * @since 1.11 1064 */ 1065 public byte[] hmac(final File valueToDigest) throws IOException { 1066 try (final BufferedInputStream stream = new BufferedInputStream(new FileInputStream(valueToDigest))) { 1067 return hmac(stream); 1068 } 1069 } 1070 1071 /** 1072 * Returns the digest for the file. 1073 * 1074 * @param valueToDigest the file to use 1075 * @return the digest as a hex String 1076 * @throws IOException 1077 * If an I/O error occurs. 1078 * @since 1.11 1079 */ 1080 public String hmacHex(final File valueToDigest) throws IOException { 1081 return Hex.encodeHexString(hmac(valueToDigest)); 1082 } 1083 1084}