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