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