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