1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.codec.digest;
19
20 import java.io.BufferedInputStream;
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.nio.ByteBuffer;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.security.InvalidKeyException;
28 import java.security.Key;
29 import java.security.NoSuchAlgorithmException;
30
31 import javax.crypto.Mac;
32 import javax.crypto.spec.SecretKeySpec;
33
34 import org.apache.commons.codec.binary.Hex;
35 import org.apache.commons.codec.binary.StringUtils;
36
37 /**
38 * Simplifies common {@link javax.crypto.Mac} tasks. This class is immutable and thread-safe.
39 * However the Mac may not be.
40 * <p>
41 * <strong>Note: Not all JCE implementations support all algorithms. If not supported, an IllegalArgumentException is
42 * thrown.</strong>
43 * </p>
44 * <p>
45 * Sample usage:
46 * </p>
47 * <pre>
48 * import static HmacAlgorithms.*;
49 * byte[] key = {1,2,3,4}; // don't use this actual key!
50 * String valueToDigest = "The quick brown fox jumps over the lazy dog";
51 * byte[] hmac = new HmacUtils(HMAC_SHA_224, key).hmac(valueToDigest);
52 * // Mac re-use
53 * HmacUtils hm1 = new HmacUtils("HmacAlgoName", key); // use a valid name here!
54 * String hexPom = hm1.hmacHex(new File("pom.xml"));
55 * String hexNot = hm1.hmacHex(new File("NOTICE.txt"));
56 * </pre>
57 * @since 1.10
58 */
59 public final class HmacUtils {
60
61 private static final int STREAM_BUFFER_LENGTH = 1024;
62
63 /**
64 * Returns an initialized {@code Mac} for the HmacMD5 algorithm.
65 * <p>
66 * Every implementation of the Java platform is required to support this standard Mac algorithm.
67 * </p>
68 *
69 * @param key
70 * The key for the keyed digest (must not be null)
71 * @return A Mac instance initialized with the given key.
72 * @see Mac#getInstance(String)
73 * @see Mac#init(Key)
74 * @throws IllegalArgumentException
75 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
76 * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_MD5, byte[])}
77 */
78 @Deprecated
79 public static Mac getHmacMd5(final byte[] key) {
80 return getInitializedMac(HmacAlgorithms.HMAC_MD5, key);
81 }
82
83 /**
84 * Returns an initialized {@code Mac} for the HmacSHA1 algorithm.
85 * <p>
86 * Every implementation of the Java platform is required to support this standard Mac algorithm.
87 * </p>
88 *
89 * @param key
90 * The key for the keyed digest (must not be null)
91 * @return A Mac instance initialized with the given key.
92 * @see Mac#getInstance(String)
93 * @see Mac#init(Key)
94 * @throws IllegalArgumentException
95 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
96 * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_1, byte[])}
97 */
98 @Deprecated
99 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 }