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.IOException; 021import java.io.InputStream; 022import java.security.InvalidKeyException; 023import java.security.Key; 024import java.security.NoSuchAlgorithmException; 025 026import javax.crypto.Mac; 027import javax.crypto.spec.SecretKeySpec; 028 029import org.apache.commons.codec.binary.Hex; 030import org.apache.commons.codec.binary.StringUtils; 031 032/** 033 * Simplifies common {@link javax.crypto.Mac} tasks. This class is immutable and thread-safe. 034 * 035 * 036 * <p> 037 * <strong>Note: Not all JCE implementations supports all algorithms. If not supported, an IllegalArgumentException is 038 * thrown.</strong> 039 * </p> 040 * 041 * @since 1.10 042 * @version $Id: HmacUtils.html 928559 2014-11-10 02:53:54Z ggregory $ 043 */ 044public final class HmacUtils { 045 046 private static final int STREAM_BUFFER_LENGTH = 1024; 047 048 /** 049 * Returns an initialized <code>Mac</code> for the HmacMD5 algorithm. 050 * <p> 051 * Every implementation of the Java platform is required to support this standard Mac algorithm. 052 * </p> 053 * 054 * @param key 055 * They key for the keyed digest (must not be null) 056 * @return A Mac instance initialized with the given key. 057 * @see Mac#getInstance(String) 058 * @see Mac#init(Key) 059 * @throws IllegalArgumentException 060 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 061 */ 062 public static Mac getHmacMd5(final byte[] key) { 063 return getInitializedMac(HmacAlgorithms.HMAC_MD5, key); 064 } 065 066 /** 067 * Returns an initialized <code>Mac</code> for the HmacSHA1 algorithm. 068 * <p> 069 * Every implementation of the Java platform is required to support this standard Mac algorithm. 070 * </p> 071 * 072 * @param key 073 * They key for the keyed digest (must not be null) 074 * @return A Mac instance initialized with the given key. 075 * @see Mac#getInstance(String) 076 * @see Mac#init(Key) 077 * @throws IllegalArgumentException 078 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 079 */ 080 public static Mac getHmacSha1(final byte[] key) { 081 return getInitializedMac(HmacAlgorithms.HMAC_SHA_1, key); 082 } 083 084 /** 085 * Returns an initialized <code>Mac</code> for the HmacSHA256 algorithm. 086 * <p> 087 * Every implementation of the Java platform is required to support this standard Mac algorithm. 088 * </p> 089 * 090 * @param key 091 * They key for the keyed digest (must not be null) 092 * @return A Mac instance initialized with the given key. 093 * @see Mac#getInstance(String) 094 * @see Mac#init(Key) 095 * @throws IllegalArgumentException 096 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 097 */ 098 public static Mac getHmacSha256(final byte[] key) { 099 return getInitializedMac(HmacAlgorithms.HMAC_SHA_256, key); 100 } 101 102 /** 103 * Returns an initialized <code>Mac</code> for the HmacSHA384 algorithm. 104 * <p> 105 * Every implementation of the Java platform is <em>not</em> required to support this Mac algorithm. 106 * </p> 107 * 108 * @param key 109 * They key for the keyed digest (must not be null) 110 * @return A Mac instance initialized with the given key. 111 * @see Mac#getInstance(String) 112 * @see Mac#init(Key) 113 * @throws IllegalArgumentException 114 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 115 */ 116 public static Mac getHmacSha384(final byte[] key) { 117 return getInitializedMac(HmacAlgorithms.HMAC_SHA_384, key); 118 } 119 120 /** 121 * Returns an initialized <code>Mac</code> for the HmacSHA512 algorithm. 122 * <p> 123 * Every implementation of the Java platform is <em>not</em> required to support this Mac algorithm. 124 * </p> 125 * 126 * @param key 127 * They key for the keyed digest (must not be null) 128 * @return A Mac instance initialized with the given key. 129 * @see Mac#getInstance(String) 130 * @see Mac#init(Key) 131 * @throws IllegalArgumentException 132 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 133 */ 134 public static Mac getHmacSha512(final byte[] key) { 135 return getInitializedMac(HmacAlgorithms.HMAC_SHA_512, key); 136 } 137 138 /** 139 * Returns an initialized <code>Mac</code> for the given <code>algorithm</code>. 140 * 141 * @param algorithm 142 * the name of the algorithm requested. See <a href= 143 * "http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA" >Appendix 144 * A in the Java Cryptography Architecture Reference Guide</a> for information about standard algorithm 145 * names. 146 * @param key 147 * They key for the keyed digest (must not be null) 148 * @return A Mac instance initialized with the given key. 149 * @see Mac#getInstance(String) 150 * @see Mac#init(Key) 151 * @throws IllegalArgumentException 152 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 153 */ 154 public static Mac getInitializedMac(final HmacAlgorithms algorithm, final byte[] key) { 155 return getInitializedMac(algorithm.toString(), key); 156 } 157 158 /** 159 * Returns an initialized <code>Mac</code> for the given <code>algorithm</code>. 160 * 161 * @param algorithm 162 * the name of the algorithm requested. See <a href= 163 * "http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA" >Appendix 164 * A in the Java Cryptography Architecture Reference Guide</a> for information about standard algorithm 165 * names. 166 * @param key 167 * They key for the keyed digest (must not be null) 168 * @return A Mac instance initialized with the given key. 169 * @see Mac#getInstance(String) 170 * @see Mac#init(Key) 171 * @throws IllegalArgumentException 172 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 173 */ 174 public static Mac getInitializedMac(final String algorithm, final byte[] key) { 175 176 if (key == null) { 177 throw new IllegalArgumentException("Null key"); 178 } 179 180 try { 181 final SecretKeySpec keySpec = new SecretKeySpec(key, algorithm); 182 final Mac mac = Mac.getInstance(algorithm); 183 mac.init(keySpec); 184 return mac; 185 } catch (final NoSuchAlgorithmException e) { 186 throw new IllegalArgumentException(e); 187 } catch (final InvalidKeyException e) { 188 throw new IllegalArgumentException(e); 189 } 190 } 191 192 // hmacMd5 193 194 /** 195 * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value. 196 * 197 * @param key 198 * They key for the keyed digest (must not be null) 199 * @param valueToDigest 200 * The value (data) which should to digest (maybe empty or null) 201 * @return HmacMD5 MAC for the given key and value 202 * @throws IllegalArgumentException 203 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 204 */ 205 public static byte[] hmacMd5(final byte[] key, final byte[] valueToDigest) { 206 try { 207 return getHmacMd5(key).doFinal(valueToDigest); 208 } catch (final IllegalStateException e) { 209 // cannot happen 210 throw new IllegalArgumentException(e); 211 } 212 } 213 214 /** 215 * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value. 216 * 217 * @param key 218 * They key for the keyed digest (must not be null) 219 * @param valueToDigest 220 * The value (data) which should to digest 221 * <p> 222 * The InputStream must not be null and will not be closed 223 * </p> 224 * @return HmacMD5 MAC for the given key and value 225 * @throws IOException 226 * If an I/O error occurs. 227 * @throws IllegalArgumentException 228 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 229 */ 230 public static byte[] hmacMd5(final byte[] key, final InputStream valueToDigest) throws IOException { 231 return updateHmac(getHmacMd5(key), valueToDigest).doFinal(); 232 } 233 234 /** 235 * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value. 236 * 237 * @param key 238 * They key for the keyed digest (must not be null) 239 * @param valueToDigest 240 * The value (data) which should to digest (maybe empty or null) 241 * @return HmacMD5 MAC for the given key and value 242 * @throws IllegalArgumentException 243 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 244 */ 245 public static byte[] hmacMd5(final String key, final String valueToDigest) { 246 return hmacMd5(StringUtils.getBytesUtf8(key), StringUtils.getBytesUtf8(valueToDigest)); 247 } 248 249 /** 250 * Returns a HmacMD5 Message Authentication Code (MAC) as a hex string (lowercase) for the given key and value. 251 * 252 * @param key 253 * They key for the keyed digest (must not be null) 254 * @param valueToDigest 255 * The value (data) which should to digest (maybe empty or null) 256 * @return HmacMD5 MAC for the given key and value as a hex string (lowercase) 257 * @throws IllegalArgumentException 258 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 259 */ 260 public static String hmacMd5Hex(final byte[] key, final byte[] valueToDigest) { 261 return Hex.encodeHexString(hmacMd5(key, valueToDigest)); 262 } 263 264 /** 265 * Returns a HmacMD5 Message Authentication Code (MAC) as a hex string (lowercase) for the given key and value. 266 * 267 * @param key 268 * They key for the keyed digest (must not be null) 269 * @param valueToDigest 270 * The value (data) which should to digest 271 * <p> 272 * The InputStream must not be null and will not be closed 273 * </p> 274 * @return HmacMD5 MAC for the given key and value as a hex string (lowercase) 275 * @throws IOException 276 * If an I/O error occurs. 277 * @throws IllegalArgumentException 278 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 279 */ 280 public static String hmacMd5Hex(final byte[] key, final InputStream valueToDigest) throws IOException { 281 return Hex.encodeHexString(hmacMd5(key, valueToDigest)); 282 } 283 284 /** 285 * Returns a HmacMD5 Message Authentication Code (MAC) as a hex string (lowercase) for the given key and value. 286 * 287 * @param key 288 * They key for the keyed digest (must not be null) 289 * @param valueToDigest 290 * The value (data) which should to digest (maybe empty or null) 291 * @return HmacMD5 MAC for the given key and value as a hex string (lowercase) 292 * @throws IllegalArgumentException 293 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 294 */ 295 public static String hmacMd5Hex(final String key, final String valueToDigest) { 296 return Hex.encodeHexString(hmacMd5(key, valueToDigest)); 297 } 298 299 // hmacSha1 300 301 /** 302 * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value. 303 * 304 * @param key 305 * They key for the keyed digest (must not be null) 306 * @param valueToDigest 307 * The value (data) which should to digest (maybe empty or null) 308 * @return HmacSHA1 MAC for the given key and value 309 * @throws IllegalArgumentException 310 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 311 */ 312 public static byte[] hmacSha1(final byte[] key, final byte[] valueToDigest) { 313 try { 314 return getHmacSha1(key).doFinal(valueToDigest); 315 } catch (final IllegalStateException e) { 316 // cannot happen 317 throw new IllegalArgumentException(e); 318 } 319 } 320 321 /** 322 * Returns a HmacSHA1 Message Authentication Code (MAC) 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 HmacSHA1 MAC for the given key and value 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 */ 337 public static byte[] hmacSha1(final byte[] key, final InputStream valueToDigest) throws IOException { 338 return updateHmac(getHmacSha1(key), valueToDigest).doFinal(); 339 } 340 341 /** 342 * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value. 343 * 344 * @param key 345 * They key for the keyed digest (must not be null) 346 * @param valueToDigest 347 * The value (data) which should to digest (maybe empty or null) 348 * @return HmacSHA1 MAC for the given key and value 349 * @throws IllegalArgumentException 350 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 351 */ 352 public static byte[] hmacSha1(final String key, final String valueToDigest) { 353 return hmacSha1(StringUtils.getBytesUtf8(key), StringUtils.getBytesUtf8(valueToDigest)); 354 } 355 356 /** 357 * Returns a HmacSHA1 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 358 * 359 * @param key 360 * They key for the keyed digest (must not be null) 361 * @param valueToDigest 362 * The value (data) which should to digest (maybe empty or null) 363 * @return HmacSHA1 MAC for the given key and value as hex string (lowercase) 364 * @throws IllegalArgumentException 365 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 366 */ 367 public static String hmacSha1Hex(final byte[] key, final byte[] valueToDigest) { 368 return Hex.encodeHexString(hmacSha1(key, valueToDigest)); 369 } 370 371 /** 372 * Returns a HmacSHA1 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 373 * 374 * @param key 375 * They key for the keyed digest (must not be null) 376 * @param valueToDigest 377 * The value (data) which should to digest 378 * <p> 379 * The InputStream must not be null and will not be closed 380 * </p> 381 * @return HmacSHA1 MAC for the given key and value as hex string (lowercase) 382 * @throws IOException 383 * If an I/O error occurs. 384 * @throws IllegalArgumentException 385 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 386 */ 387 public static String hmacSha1Hex(final byte[] key, final InputStream valueToDigest) throws IOException { 388 return Hex.encodeHexString(hmacSha1(key, valueToDigest)); 389 } 390 391 /** 392 * Returns a HmacSHA1 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 393 * 394 * @param key 395 * They key for the keyed digest (must not be null) 396 * @param valueToDigest 397 * The value (data) which should to digest (maybe empty or null) 398 * @return HmacSHA1 MAC for the given key and value as hex string (lowercase) 399 * @throws IllegalArgumentException 400 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 401 */ 402 public static String hmacSha1Hex(final String key, final String valueToDigest) { 403 return Hex.encodeHexString(hmacSha1(key, valueToDigest)); 404 } 405 406 // hmacSha256 407 408 /** 409 * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value. 410 * 411 * @param key 412 * They key for the keyed digest (must not be null) 413 * @param valueToDigest 414 * The value (data) which should to digest (maybe empty or null) 415 * @return HmacSHA256 MAC for the given key and value 416 * @throws IllegalArgumentException 417 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 418 */ 419 public static byte[] hmacSha256(final byte[] key, final byte[] valueToDigest) { 420 try { 421 return getHmacSha256(key).doFinal(valueToDigest); 422 } catch (final IllegalStateException e) { 423 // cannot happen 424 throw new IllegalArgumentException(e); 425 } 426 } 427 428 /** 429 * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value. 430 * 431 * @param key 432 * They key for the keyed digest (must not be null) 433 * @param valueToDigest 434 * The value (data) which should to digest 435 * <p> 436 * The InputStream must not be null and will not be closed 437 * </p> 438 * @return HmacSHA256 MAC for the given key and value 439 * @throws IOException 440 * If an I/O error occurs. 441s * @throws IllegalArgumentException 442 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 443 */ 444 public static byte[] hmacSha256(final byte[] key, final InputStream valueToDigest) throws IOException { 445 return updateHmac(getHmacSha256(key), valueToDigest).doFinal(); 446 } 447 448 /** 449 * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value. 450 * 451 * @param key 452 * They key for the keyed digest (must not be null) 453 * @param valueToDigest 454 * The value (data) which should to digest (maybe empty or null) 455 * @return HmacSHA256 MAC for the given key and value 456 * @throws IllegalArgumentException 457 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 458 */ 459 public static byte[] hmacSha256(final String key, final String valueToDigest) { 460 return hmacSha256(StringUtils.getBytesUtf8(key), StringUtils.getBytesUtf8(valueToDigest)); 461 } 462 463 /** 464 * Returns a HmacSHA256 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 465 * 466 * @param key 467 * They key for the keyed digest (must not be null) 468 * @param valueToDigest 469 * The value (data) which should to digest (maybe empty or null) 470 * @return HmacSHA256 MAC for the given key and value as hex string (lowercase) 471 * @throws IllegalArgumentException 472 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 473 */ 474 public static String hmacSha256Hex(final byte[] key, final byte[] valueToDigest) { 475 return Hex.encodeHexString(hmacSha256(key, valueToDigest)); 476 } 477 478 /** 479 * Returns a HmacSHA256 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 480 * 481 * @param key 482 * They key for the keyed digest (must not be null) 483 * @param valueToDigest 484 * The value (data) which should to digest 485 * <p> 486 * The InputStream must not be null and will not be closed 487 * </p> 488 * @return HmacSHA256 MAC for the given key and value as hex string (lowercase) 489 * @throws IOException 490 * If an I/O error occurs. 491 * @throws IllegalArgumentException 492 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 493 */ 494 public static String hmacSha256Hex(final byte[] key, final InputStream valueToDigest) throws IOException { 495 return Hex.encodeHexString(hmacSha256(key, valueToDigest)); 496 } 497 498 /** 499 * Returns a HmacSHA256 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 500 * 501 * @param key 502 * They key for the keyed digest (must not be null) 503 * @param valueToDigest 504 * The value (data) which should to digest (maybe empty or null) 505 * @return HmacSHA256 MAC for the given key and value as hex string (lowercase) 506 * @throws IllegalArgumentException 507 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 508 */ 509 public static String hmacSha256Hex(final String key, final String valueToDigest) { 510 return Hex.encodeHexString(hmacSha256(key, valueToDigest)); 511 } 512 513 // hmacSha384 514 515 /** 516 * Returns a HmacSHA384 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 HmacSHA384 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 */ 526 public static byte[] hmacSha384(final byte[] key, final byte[] valueToDigest) { 527 try { 528 return getHmacSha384(key).doFinal(valueToDigest); 529 } catch (final IllegalStateException e) { 530 // cannot happen 531 throw new IllegalArgumentException(e); 532 } 533 } 534 535 /** 536 * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value. 537 * 538 * @param key 539 * They key for the keyed digest (must not be null) 540 * @param valueToDigest 541 * The value (data) which should to digest 542 * <p> 543 * The InputStream must not be null and will not be closed 544 * </p> 545 * @return HmacSHA384 MAC for the given key and value 546 * @throws IOException 547 * If an I/O error occurs. 548 * @throws IllegalArgumentException 549 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 550 */ 551 public static byte[] hmacSha384(final byte[] key, final InputStream valueToDigest) throws IOException { 552 return updateHmac(getHmacSha384(key), valueToDigest).doFinal(); 553 } 554 555 /** 556 * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value. 557 * 558 * @param key 559 * They key for the keyed digest (must not be null) 560 * @param valueToDigest 561 * The value (data) which should to digest (maybe empty or null) 562 * @return HmacSHA384 MAC for the given key and value 563 * @throws IllegalArgumentException 564 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 565 */ 566 public static byte[] hmacSha384(final String key, final String valueToDigest) { 567 return hmacSha384(StringUtils.getBytesUtf8(key), StringUtils.getBytesUtf8(valueToDigest)); 568 } 569 570 /** 571 * Returns a HmacSHA384 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 572 * 573 * @param key 574 * They key for the keyed digest (must not be null) 575 * @param valueToDigest 576 * The value (data) which should to digest (maybe empty or null) 577 * @return HmacSHA384 MAC for the given key and value as hex string (lowercase) 578 * @throws IllegalArgumentException 579 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 580 */ 581 public static String hmacSha384Hex(final byte[] key, final byte[] valueToDigest) { 582 return Hex.encodeHexString(hmacSha384(key, valueToDigest)); 583 } 584 585 /** 586 * Returns a HmacSHA384 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 587 * 588 * @param key 589 * They key for the keyed digest (must not be null) 590 * @param valueToDigest 591 * The value (data) which should to digest 592 * <p> 593 * The InputStream must not be null and will not be closed 594 * </p> 595 * @return HmacSHA384 MAC for the given key and value as hex string (lowercase) 596 * @throws IOException 597 * If an I/O error occurs. 598 * @throws IllegalArgumentException 599 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 600 */ 601 public static String hmacSha384Hex(final byte[] key, final InputStream valueToDigest) throws IOException { 602 return Hex.encodeHexString(hmacSha384(key, valueToDigest)); 603 } 604 605 /** 606 * Returns a HmacSHA384 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 607 * 608 * @param key 609 * They key for the keyed digest (must not be null) 610 * @param valueToDigest 611 * The value (data) which should to digest (maybe empty or null) 612 * @return HmacSHA384 MAC for the given key and value as hex string (lowercase) 613 * @throws IllegalArgumentException 614 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 615 */ 616 public static String hmacSha384Hex(final String key, final String valueToDigest) { 617 return Hex.encodeHexString(hmacSha384(key, valueToDigest)); 618 } 619 620 // hmacSha512 621 622 /** 623 * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value. 624 * 625 * @param key 626 * They key for the keyed digest (must not be null) 627 * @param valueToDigest 628 * The value (data) which should to digest (maybe empty or null) 629 * @return HmacSHA512 MAC for the given key and value 630 * @throws IllegalArgumentException 631 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 632 */ 633 public static byte[] hmacSha512(final byte[] key, final byte[] valueToDigest) { 634 try { 635 return getHmacSha512(key).doFinal(valueToDigest); 636 } catch (final IllegalStateException e) { 637 // cannot happen 638 throw new IllegalArgumentException(e); 639 } 640 } 641 642 /** 643 * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value. 644 * 645 * @param key 646 * They key for the keyed digest (must not be null) 647 * @param valueToDigest 648 * The value (data) which should to digest 649 * <p> 650 * The InputStream must not be null and will not be closed 651 * </p> 652 * @return HmacSHA512 MAC for the given key and value 653 * @throws IOException 654 * If an I/O error occurs. 655 * @throws IllegalArgumentException 656 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 657 */ 658 public static byte[] hmacSha512(final byte[] key, final InputStream valueToDigest) throws IOException { 659 return updateHmac(getHmacSha512(key), valueToDigest).doFinal(); 660 } 661 662 /** 663 * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value. 664 * 665 * @param key 666 * They key for the keyed digest (must not be null) 667 * @param valueToDigest 668 * The value (data) which should to digest (maybe empty or null) 669 * @return HmacSHA512 MAC for the given key and value 670 * @throws IllegalArgumentException 671 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 672 */ 673 public static byte[] hmacSha512(final String key, final String valueToDigest) { 674 return hmacSha512(StringUtils.getBytesUtf8(key), StringUtils.getBytesUtf8(valueToDigest)); 675 } 676 677 /** 678 * Returns a HmacSHA512 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 679 * 680 * @param key 681 * They key for the keyed digest (must not be null) 682 * @param valueToDigest 683 * The value (data) which should to digest (maybe empty or null) 684 * @return HmacSHA512 MAC for the given key and value as hex string (lowercase) 685 * @throws IllegalArgumentException 686 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 687 */ 688 public static String hmacSha512Hex(final byte[] key, final byte[] valueToDigest) { 689 return Hex.encodeHexString(hmacSha512(key, valueToDigest)); 690 } 691 692 /** 693 * Returns a HmacSHA512 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 694 * 695 * @param key 696 * They key for the keyed digest (must not be null) 697 * @param valueToDigest 698 * The value (data) which should to digest 699 * <p> 700 * The InputStream must not be null and will not be closed 701 * </p> 702 * @return HmacSHA512 MAC for the given key and value as hex string (lowercase) 703 * @throws IOException 704 * If an I/O error occurs. 705 * @throws IllegalArgumentException 706 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 707 */ 708 public static String hmacSha512Hex(final byte[] key, final InputStream valueToDigest) throws IOException { 709 return Hex.encodeHexString(hmacSha512(key, valueToDigest)); 710 } 711 712 /** 713 * Returns a HmacSHA512 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value. 714 * 715 * @param key 716 * They key for the keyed digest (must not be null) 717 * @param valueToDigest 718 * The value (data) which should to digest (maybe empty or null) 719 * @return HmacSHA512 MAC for the given key and value as hex string (lowercase) 720 * @throws IllegalArgumentException 721 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid. 722 */ 723 public static String hmacSha512Hex(final String key, final String valueToDigest) { 724 return Hex.encodeHexString(hmacSha512(key, valueToDigest)); 725 } 726 727 // update 728 729 /** 730 * Updates the given {@link Mac}. This generates a digest for valueToDigest and the key the Mac was initialized 731 * 732 * @param mac 733 * the initialized {@link Mac} to update 734 * @param valueToDigest 735 * the value to update the {@link Mac} with (maybe null or empty) 736 * @return the updated {@link Mac} 737 * @throws IllegalStateException 738 * if the Mac was not initialized 739 * @since 1.x 740 */ 741 public static Mac updateHmac(final Mac mac, final byte[] valueToDigest) { 742 mac.reset(); 743 mac.update(valueToDigest); 744 return mac; 745 } 746 747 /** 748 * Updates the given {@link Mac}. This generates a digest for valueToDigest and the key the Mac was initialized 749 * 750 * @param mac 751 * the initialized {@link Mac} to update 752 * @param valueToDigest 753 * the value to update the {@link Mac} with 754 * <p> 755 * The InputStream must not be null and will not be closed 756 * </p> 757 * @return the updated {@link Mac} 758 * @throws IOException 759 * If an I/O error occurs. 760 * @throws IllegalStateException 761 * If the Mac was not initialized 762 * @since 1.x 763 */ 764 public static Mac updateHmac(final Mac mac, final InputStream valueToDigest) throws IOException { 765 mac.reset(); 766 final byte[] buffer = new byte[STREAM_BUFFER_LENGTH]; 767 int read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH); 768 769 while (read > -1) { 770 mac.update(buffer, 0, read); 771 read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH); 772 } 773 774 return mac; 775 } 776 777 /** 778 * Updates the given {@link Mac}. This generates a digest for valueToDigest and the key the Mac was initialized 779 * 780 * @param mac 781 * the initialized {@link Mac} to update 782 * @param valueToDigest 783 * the value to update the {@link Mac} with (maybe null or empty) 784 * @return the updated {@link Mac} 785 * @throws IllegalStateException 786 * if the Mac was not initialized 787 * @since 1.x 788 */ 789 public static Mac updateHmac(final Mac mac, final String valueToDigest) { 790 mac.reset(); 791 mac.update(StringUtils.getBytesUtf8(valueToDigest)); 792 return mac; 793 } 794}