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