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 if (key == null) {
200 throw new IllegalArgumentException("Null key");
201 }
202 try {
203 final SecretKeySpec keySpec = new SecretKeySpec(key, algorithm);
204 final Mac mac = Mac.getInstance(algorithm);
205 mac.init(keySpec);
206 return mac;
207 } catch (final NoSuchAlgorithmException | InvalidKeyException e) {
208 throw new IllegalArgumentException(e);
209 }
210 }
211
212 /**
213 * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value.
214 *
215 * @param key
216 * The key for the keyed digest (must not be null)
217 * @param valueToDigest
218 * The value (data) which should to digest (maybe empty or null)
219 * @return HmacMD5 MAC for the given key and value
220 * @throws IllegalArgumentException
221 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
222 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmac(byte[])}
223 */
224 @Deprecated
225 public static byte[] hmacMd5(final byte[] key, final byte[] valueToDigest) {
226 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmac(valueToDigest);
227 }
228
229 /**
230 * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value.
231 *
232 * @param key
233 * The key for the keyed digest (must not be null)
234 * @param valueToDigest
235 * The value (data) which should to digest
236 * <p>
237 * The InputStream must not be null and will not be closed
238 * </p>
239 * @return HmacMD5 MAC for the given key and value
240 * @throws IOException
241 * If an I/O error occurs.
242 * @throws IllegalArgumentException
243 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
244 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmac(InputStream)}
245 */
246 @Deprecated
247 public static byte[] hmacMd5(final byte[] key, final InputStream valueToDigest) throws IOException {
248 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmac(valueToDigest);
249 }
250
251 /**
252 * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value.
253 *
254 * @param key
255 * The key for the keyed digest (must not be null)
256 * @param valueToDigest
257 * The value (data) which should to digest (maybe empty or null)
258 * @return HmacMD5 MAC for the given key and value
259 * @throws IllegalArgumentException
260 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
261 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, String).hmac(String)}
262 */
263 @Deprecated
264 public static byte[] hmacMd5(final String key, final String valueToDigest) {
265 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmac(valueToDigest);
266 }
267
268 /**
269 * Returns a HmacMD5 Message Authentication Code (MAC) as a hexadecimal string (lowercase) for the given key and value.
270 *
271 * @param key
272 * The key for the keyed digest (must not be null)
273 * @param valueToDigest
274 * The value (data) which should to digest (maybe empty or null)
275 * @return HmacMD5 MAC for the given key and value as a hexadecimal string (lowercase)
276 * @throws IllegalArgumentException
277 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
278 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmacHex(byte[])}
279 */
280 @Deprecated
281 public static String hmacMd5Hex(final byte[] key, final byte[] valueToDigest) {
282 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(valueToDigest);
283 }
284
285 /**
286 * Returns a HmacMD5 Message Authentication Code (MAC) as a hexadecimal string (lowercase) for the given key and value.
287 *
288 * @param key
289 * The key for the keyed digest (must not be null)
290 * @param valueToDigest
291 * The value (data) which should to digest
292 * <p>
293 * The InputStream must not be null and will not be closed
294 * </p>
295 * @return HmacMD5 MAC for the given key and value as a hexadecimal string (lowercase)
296 * @throws IOException
297 * If an I/O error occurs.
298 * @throws IllegalArgumentException
299 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
300 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmacHex(InputStream)}
301 */
302 @Deprecated
303 public static String hmacMd5Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
304 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(valueToDigest);
305 }
306
307 /**
308 * Returns a HmacMD5 Message Authentication Code (MAC) as a hexadecimal string (lowercase) for the given key and value.
309 *
310 * @param key
311 * The key for the keyed digest (must not be null)
312 * @param valueToDigest
313 * The value (data) which should to digest (maybe empty or null)
314 * @return HmacMD5 MAC for the given key and value as a hexadecimal string (lowercase)
315 * @throws IllegalArgumentException
316 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
317 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, String).hmacHex(String)}
318 */
319 @Deprecated
320 public static String hmacMd5Hex(final String key, final String valueToDigest) {
321 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(valueToDigest);
322 }
323
324 /**
325 * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value.
326 *
327 * @param key
328 * The key for the keyed digest (must not be null)
329 * @param valueToDigest
330 * The value (data) which should to digest (maybe empty or null)
331 * @return HmacSHA1 MAC for the given key and value
332 * @throws IllegalArgumentException
333 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
334 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmac(byte[])}
335 */
336 @Deprecated
337 public static byte[] hmacSha1(final byte[] key, final byte[] valueToDigest) {
338 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmac(valueToDigest);
339 }
340
341 /**
342 * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value.
343 *
344 * @param key
345 * The key for the keyed digest (must not be null)
346 * @param valueToDigest
347 * The value (data) which should to digest
348 * <p>
349 * The InputStream must not be null and will not be closed
350 * </p>
351 * @return HmacSHA1 MAC for the given key and value
352 * @throws IOException
353 * If an I/O error occurs.
354 * @throws IllegalArgumentException
355 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
356 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmac(InputStream)}
357 */
358 @Deprecated
359 public static byte[] hmacSha1(final byte[] key, final InputStream valueToDigest) throws IOException {
360 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmac(valueToDigest);
361 }
362
363 /**
364 * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value.
365 *
366 * @param key
367 * The 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, String).hmac(String)}
374 */
375 @Deprecated
376 public static byte[] hmacSha1(final String key, final String valueToDigest) {
377 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmac(valueToDigest);
378 }
379
380 // hmacSha1
381
382 /**
383 * Returns a HmacSHA1 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
384 *
385 * @param key
386 * The key for the keyed digest (must not be null)
387 * @param valueToDigest
388 * The value (data) which should to digest (maybe empty or null)
389 * @return HmacSHA1 MAC for the given key and value as hexadecimal string (lowercase)
390 * @throws IllegalArgumentException
391 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
392 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmacHex(byte[])}
393 */
394 @Deprecated
395 public static String hmacSha1Hex(final byte[] key, final byte[] valueToDigest) {
396 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(valueToDigest);
397 }
398
399 /**
400 * Returns a HmacSHA1 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
401 *
402 * @param key
403 * The key for the keyed digest (must not be null)
404 * @param valueToDigest
405 * The value (data) which should to digest
406 * <p>
407 * The InputStream must not be null and will not be closed
408 * </p>
409 * @return HmacSHA1 MAC for the given key and value as hexadecimal string (lowercase)
410 * @throws IOException
411 * If an I/O error occurs.
412 * @throws IllegalArgumentException
413 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
414 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmacHex(InputStream)}
415 */
416 @Deprecated
417 public static String hmacSha1Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
418 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(valueToDigest);
419 }
420
421 /**
422 * Returns a HmacSHA1 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
423 *
424 * @param key
425 * The key for the keyed digest (must not be null)
426 * @param valueToDigest
427 * The value (data) which should to digest (maybe empty or null)
428 * @return HmacSHA1 MAC for the given key and value as hexadecimal string (lowercase)
429 * @throws IllegalArgumentException
430 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
431 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, String).hmacHex(String)}
432 */
433 @Deprecated
434 public static String hmacSha1Hex(final String key, final String valueToDigest) {
435 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(valueToDigest);
436 }
437
438 /**
439 * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value.
440 *
441 * @param key
442 * The key for the keyed digest (must not be null)
443 * @param valueToDigest
444 * The value (data) which should to digest (maybe empty or null)
445 * @return HmacSHA256 MAC for the given key and value
446 * @throws IllegalArgumentException
447 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
448 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmac(byte[])}
449 */
450 @Deprecated
451 public static byte[] hmacSha256(final byte[] key, final byte[] valueToDigest) {
452 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(valueToDigest);
453 }
454
455 /**
456 * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value.
457 *
458 * @param key
459 * The key for the keyed digest (must not be null)
460 * @param valueToDigest
461 * The value (data) which should to digest
462 * <p>
463 * The InputStream must not be null and will not be closed
464 * </p>
465 * @return HmacSHA256 MAC for the given key and value
466 * @throws IOException
467 * If an I/O error occurs.
468 * @throws IllegalArgumentException
469 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
470 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmac(InputStream)}
471 */
472 @Deprecated
473 public static byte[] hmacSha256(final byte[] key, final InputStream valueToDigest) throws IOException {
474 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(valueToDigest);
475 }
476
477 /**
478 * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value.
479 *
480 * @param key
481 * The 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, String).hmac(String)}
488 */
489 @Deprecated
490 public static byte[] hmacSha256(final String key, final String valueToDigest) {
491 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(valueToDigest);
492 }
493
494 /**
495 * Returns a HmacSHA256 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
496 *
497 * @param key
498 * The key for the keyed digest (must not be null)
499 * @param valueToDigest
500 * The value (data) which should to digest (maybe empty or null)
501 * @return HmacSHA256 MAC for the given key and value as hexadecimal string (lowercase)
502 * @throws IllegalArgumentException
503 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
504 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmacHex(byte[])}
505 */
506 @Deprecated
507 public static String hmacSha256Hex(final byte[] key, final byte[] valueToDigest) {
508 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest);
509 }
510
511 /**
512 * Returns a HmacSHA256 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
513 *
514 * @param key
515 * The key for the keyed digest (must not be null)
516 * @param valueToDigest
517 * The value (data) which should to digest
518 * <p>
519 * The InputStream must not be null and will not be closed
520 * </p>
521 * @return HmacSHA256 MAC for the given key and value as hexadecimal string (lowercase)
522 * @throws IOException
523 * If an I/O error occurs.
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, byte[]).hmacHex(InputStream)}
527 */
528 @Deprecated
529 public static String hmacSha256Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
530 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest);
531 }
532
533 /**
534 * Returns a HmacSHA256 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
535 *
536 * @param key
537 * The 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 hexadecimal 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, String).hmacHex(String)}
544 */
545 @Deprecated
546 public static String hmacSha256Hex(final String key, final String valueToDigest) {
547 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest);
548 }
549
550 /**
551 * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value.
552 *
553 * @param key
554 * The key for the keyed digest (must not be null)
555 * @param valueToDigest
556 * The value (data) which should to digest (maybe empty or null)
557 * @return HmacSHA384 MAC for the given key and value
558 * @throws IllegalArgumentException
559 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
560 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmac(byte[])}
561 */
562 @Deprecated
563 public static byte[] hmacSha384(final byte[] key, final byte[] valueToDigest) {
564 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest);
565 }
566
567 /**
568 * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value.
569 *
570 * @param key
571 * The key for the keyed digest (must not be null)
572 * @param valueToDigest
573 * The value (data) which should to digest
574 * <p>
575 * The InputStream must not be null and will not be closed
576 * </p>
577 * @return HmacSHA384 MAC for the given key and value
578 * @throws IOException
579 * If an I/O error occurs.
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_384, byte[]).hmac(InputStream)}
583 */
584 @Deprecated
585 public static byte[] hmacSha384(final byte[] key, final InputStream valueToDigest) throws IOException {
586 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest);
587 }
588
589 /**
590 * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value.
591 *
592 * @param key
593 * The key for the keyed digest (must not be null)
594 * @param valueToDigest
595 * The value (data) which should to digest (maybe empty or null)
596 * @return HmacSHA384 MAC for the given key and value
597 * @throws IllegalArgumentException
598 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
599 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, String).hmac(String)}
600 */
601 @Deprecated
602 public static byte[] hmacSha384(final String key, final String valueToDigest) {
603 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest);
604 }
605
606 // hmacSha384
607
608 /**
609 * Returns a HmacSHA384 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
610 *
611 * @param key
612 * The key for the keyed digest (must not be null)
613 * @param valueToDigest
614 * The value (data) which should to digest (maybe empty or null)
615 * @return HmacSHA384 MAC for the given key and value as hexadecimal string (lowercase)
616 * @throws IllegalArgumentException
617 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
618 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmacHex(byte[])}
619 */
620 @Deprecated
621 public static String hmacSha384Hex(final byte[] key, final byte[] valueToDigest) {
622 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest);
623 }
624
625 /**
626 * Returns a HmacSHA384 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
627 *
628 * @param key
629 * The key for the keyed digest (must not be null)
630 * @param valueToDigest
631 * The value (data) which should to digest
632 * <p>
633 * The InputStream must not be null and will not be closed
634 * </p>
635 * @return HmacSHA384 MAC for the given key and value as hexadecimal string (lowercase)
636 * @throws IOException
637 * If an I/O error occurs.
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, byte[]).hmacHex(InputStream)}
641 */
642 @Deprecated
643 public static String hmacSha384Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
644 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest);
645 }
646
647 /**
648 * Returns a HmacSHA384 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
649 *
650 * @param key
651 * The 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 hexadecimal 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, String).hmacHex(String)}
658 */
659 @Deprecated
660 public static String hmacSha384Hex(final String key, final String valueToDigest) {
661 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest);
662 }
663
664 /**
665 * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value.
666 *
667 * @param key
668 * The key for the keyed digest (must not be null)
669 * @param valueToDigest
670 * The value (data) which should to digest (maybe empty or null)
671 * @return HmacSHA512 MAC for the given key and value
672 * @throws IllegalArgumentException
673 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
674 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmac(byte[])}
675 */
676 @Deprecated
677 public static byte[] hmacSha512(final byte[] key, final byte[] valueToDigest) {
678 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest);
679 }
680
681 /**
682 * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value.
683 *
684 * @param key
685 * The key for the keyed digest (must not be null)
686 * @param valueToDigest
687 * The value (data) which should to digest
688 * <p>
689 * The InputStream must not be null and will not be closed
690 * </p>
691 * @return HmacSHA512 MAC for the given key and value
692 * @throws IOException
693 * If an I/O error occurs.
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_512, byte[]).hmac(InputStream)}
697 */
698 @Deprecated
699 public static byte[] hmacSha512(final byte[] key, final InputStream valueToDigest) throws IOException {
700 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest);
701 }
702
703 /**
704 * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value.
705 *
706 * @param key
707 * The key for the keyed digest (must not be null)
708 * @param valueToDigest
709 * The value (data) which should to digest (maybe empty or null)
710 * @return HmacSHA512 MAC for the given key and value
711 * @throws IllegalArgumentException
712 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
713 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, String).hmac(String)}
714 */
715 @Deprecated
716 public static byte[] hmacSha512(final String key, final String valueToDigest) {
717 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest);
718 }
719
720 // hmacSha512
721
722 /**
723 * Returns a HmacSHA512 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
724 *
725 * @param key
726 * The key for the keyed digest (must not be null)
727 * @param valueToDigest
728 * The value (data) which should to digest (maybe empty or null)
729 * @return HmacSHA512 MAC for the given key and value as hexadecimal string (lowercase)
730 * @throws IllegalArgumentException
731 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
732 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmacHex(byte[])}
733 */
734 @Deprecated
735 public static String hmacSha512Hex(final byte[] key, final byte[] valueToDigest) {
736 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest);
737 }
738
739 /**
740 * Returns a HmacSHA512 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
741 *
742 * @param key
743 * The key for the keyed digest (must not be null)
744 * @param valueToDigest
745 * The value (data) which should to digest
746 * <p>
747 * The InputStream must not be null and will not be closed
748 * </p>
749 * @return HmacSHA512 MAC for the given key and value as hexadecimal string (lowercase)
750 * @throws IOException
751 * If an I/O error occurs.
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, byte[]).hmacHex(InputStream)}
755 */
756 @Deprecated
757 public static String hmacSha512Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
758 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest);
759 }
760
761 /**
762 * Returns a HmacSHA512 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
763 *
764 * @param key
765 * The 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 hexadecimal 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, String).hmacHex(String)}
772 */
773 @Deprecated
774 public static String hmacSha512Hex(final String key, final String valueToDigest) {
775 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest);
776 }
777
778 /**
779 * Returns whether this algorithm is available
780 *
781 * @param name the name to check
782 * @return whether this algorithm is available
783 * @since 1.11
784 */
785 public static boolean isAvailable(final HmacAlgorithms name) {
786 try {
787 Mac.getInstance(name.getName());
788 return true;
789 } catch (final NoSuchAlgorithmException e) {
790 return false;
791 }
792 }
793
794 /**
795 * Returns whether this algorithm is available
796 *
797 * @param name the name to check
798 * @return whether this algorithm is available
799 * @since 1.11
800 */
801 public static boolean isAvailable(final String name) {
802 try {
803 Mac.getInstance(name);
804 return true;
805 } catch (final NoSuchAlgorithmException e) {
806 return false;
807 }
808 }
809
810 /**
811 * Resets and then updates the given {@link Mac} with the value.
812 *
813 * @param mac
814 * the initialized {@link Mac} to update
815 * @param valueToDigest
816 * the value to update the {@link Mac} with (maybe null or empty)
817 * @return the updated {@link Mac}
818 * @throws IllegalStateException
819 * if the Mac was not initialized
820 */
821 public static Mac updateHmac(final Mac mac, final byte[] valueToDigest) {
822 mac.reset();
823 mac.update(valueToDigest);
824 return mac;
825 }
826
827 /**
828 * Resets and then updates the given {@link Mac} with the value.
829 *
830 * @param mac
831 * the initialized {@link Mac} to update
832 * @param valueToDigest
833 * the value to update the {@link Mac} with
834 * <p>
835 * The InputStream must not be null and will not be closed
836 * </p>
837 * @return the updated {@link Mac}
838 * @throws IOException
839 * If an I/O error occurs.
840 * @throws IllegalStateException
841 * If the Mac was not initialized
842 */
843 public static Mac updateHmac(final Mac mac, final InputStream valueToDigest) throws IOException {
844 mac.reset();
845 final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
846 int read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH);
847
848 while (read > -1) {
849 mac.update(buffer, 0, read);
850 read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH);
851 }
852
853 return mac;
854 }
855
856 /**
857 * Resets and then updates the given {@link Mac} with the value.
858 *
859 * @param mac
860 * the initialized {@link Mac} to update
861 * @param valueToDigest
862 * the value to update the {@link Mac} with (maybe null or empty)
863 * @return the updated {@link Mac}
864 * @throws IllegalStateException
865 * if the Mac was not initialized
866 */
867 public static Mac updateHmac(final Mac mac, final String valueToDigest) {
868 mac.reset();
869 mac.update(StringUtils.getBytesUtf8(valueToDigest));
870 return mac;
871 }
872
873 private final Mac mac;
874
875 /**
876 * Preserves binary compatibility only.
877 * As for previous versions does not provide useful behavior
878 * @deprecated since 1.11; only useful to preserve binary compatibility
879 */
880 @Deprecated
881 public HmacUtils() {
882 this(null);
883 }
884
885 /**
886 * Creates an instance using the provided algorithm type.
887 *
888 * @param algorithm to use.
889 * @param key the key to use
890 * @throws IllegalArgumentException
891 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
892 * @since 1.11
893 */
894 public HmacUtils(final HmacAlgorithms algorithm, final byte[] key) {
895 this(algorithm.getName(), key);
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 HmacAlgorithms algorithm, final String key) {
908 this(algorithm.getName(), StringUtils.getBytesUtf8(key));
909 }
910
911 private HmacUtils(final Mac mac) {
912 this.mac = mac;
913 }
914
915 /**
916 * Creates an instance using the provided algorithm type.
917 *
918 * @param algorithm to use
919 * @param key the key to use
920 * @throws IllegalArgumentException
921 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
922 * @since 1.11
923 */
924 public HmacUtils(final String algorithm, final byte[] key) {
925 this(getInitializedMac(algorithm, key));
926 }
927
928 /**
929 * Creates an instance using the provided algorithm type.
930 *
931 * @param algorithm to use
932 * @param key the key to use
933 * @throws IllegalArgumentException
934 * when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
935 * @since 1.11
936 */
937 public HmacUtils(final String algorithm, final String key) {
938 this(algorithm, StringUtils.getBytesUtf8(key));
939 }
940
941 /**
942 * Returns the digest for the input data.
943 *
944 * @param valueToDigest the input to use
945 * @return the digest as a byte[]
946 * @since 1.11
947 */
948 public byte[] hmac(final byte[] valueToDigest) {
949 return mac.doFinal(valueToDigest);
950 }
951
952 /**
953 * Returns the digest for the input data.
954 *
955 * @param valueToDigest the input to use
956 * @return the digest as a byte[]
957 * @since 1.11
958 */
959 public byte[] hmac(final ByteBuffer valueToDigest) {
960 mac.update(valueToDigest);
961 return mac.doFinal();
962 }
963
964 /**
965 * Returns the digest for the file.
966 *
967 * @param valueToDigest the file to use
968 * @return the digest
969 * @throws IOException
970 * If an I/O error occurs.
971 * @since 1.11
972 */
973 public byte[] hmac(final File valueToDigest) throws IOException {
974 try (final BufferedInputStream stream = new BufferedInputStream(new FileInputStream(valueToDigest))) {
975 return hmac(stream);
976 }
977 }
978
979 /**
980 * Returns the digest for the stream.
981 *
982 * @param valueToDigest
983 * the data to use
984 * <p>
985 * The InputStream must not be null and will not be closed
986 * </p>
987 * @return the digest
988 * @throws IOException
989 * If an I/O error occurs.
990 * @since 1.11
991 */
992 public byte[] hmac(final InputStream valueToDigest) throws IOException {
993 final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
994 int read;
995
996 while ((read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH)) > -1) {
997 mac.update(buffer, 0, read);
998 }
999 return mac.doFinal();
1000 }
1001
1002 /**
1003 * Returns the digest for the input data.
1004 *
1005 * @param valueToDigest the input to use, treated as UTF-8
1006 * @return the digest as a byte[]
1007 * @since 1.11
1008 */
1009 public byte[] hmac(final String valueToDigest) {
1010 return mac.doFinal(StringUtils.getBytesUtf8(valueToDigest));
1011 }
1012
1013 /**
1014 * Returns the digest for the input data.
1015 *
1016 * @param valueToDigest the input to use
1017 * @return the digest as a hexadecimal String
1018 * @since 1.11
1019 */
1020 public String hmacHex(final byte[] valueToDigest) {
1021 return Hex.encodeHexString(hmac(valueToDigest));
1022 }
1023
1024 /**
1025 * Returns the digest for the input data.
1026 *
1027 * @param valueToDigest the input to use
1028 * @return the digest as a hexadecimal String
1029 * @since 1.11
1030 */
1031 public String hmacHex(final ByteBuffer valueToDigest) {
1032 return Hex.encodeHexString(hmac(valueToDigest));
1033 }
1034
1035 /**
1036 * Returns the digest for the file.
1037 *
1038 * @param valueToDigest the file to use
1039 * @return the digest as a hexadecimal String
1040 * @throws IOException
1041 * If an I/O error occurs.
1042 * @since 1.11
1043 */
1044 public String hmacHex(final File valueToDigest) throws IOException {
1045 return Hex.encodeHexString(hmac(valueToDigest));
1046 }
1047
1048 /**
1049 * Returns the digest for the stream.
1050 *
1051 * @param valueToDigest
1052 * the data to use
1053 * <p>
1054 * The InputStream must not be null and will not be closed
1055 * </p>
1056 * @return the digest as a hexadecimal String
1057 * @throws IOException
1058 * If an I/O error occurs.
1059 * @since 1.11
1060 */
1061 public String hmacHex(final InputStream valueToDigest) throws IOException {
1062 return Hex.encodeHexString(hmac(valueToDigest));
1063 }
1064
1065 /**
1066 * Returns the digest for the input data.
1067 *
1068 * @param valueToDigest the input to use, treated as UTF-8
1069 * @return the digest as a hexadecimal String
1070 * @since 1.11
1071 */
1072 public String hmacHex(final String valueToDigest) {
1073 return Hex.encodeHexString(hmac(valueToDigest));
1074 }
1075
1076 }