1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.codec.digest;
19
20 import java.io.BufferedInputStream;
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.nio.ByteBuffer;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.security.InvalidKeyException;
28 import java.security.Key;
29 import java.security.NoSuchAlgorithmException;
30
31 import javax.crypto.Mac;
32 import javax.crypto.spec.SecretKeySpec;
33
34 import org.apache.commons.codec.binary.Hex;
35 import org.apache.commons.codec.binary.StringUtils;
36
37 /**
38 * Simplifies common {@link Mac} tasks. This class is immutable and thread-safe. However the Mac may not be.
39 * <p>
40 * <strong>Note: Not all JCE implementations support all algorithms. If not supported, an IllegalArgumentException is thrown.</strong>
41 * </p>
42 * <p>
43 * Sample usage:
44 * </p>
45 *
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 reuse
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 *
57 * @since 1.10
58 */
59 public final class HmacUtils {
60
61 private static final int STREAM_BUFFER_LENGTH = 1024;
62
63 /**
64 * Gets an initialized {@link Mac} for the HmacMD5 algorithm.
65 * <p>
66 * Every implementation of the Java platform is required to support this standard Mac algorithm.
67 * </p>
68 *
69 * @param key The key for the keyed digest (must not be null).
70 * @return A Mac instance initialized with the given key.
71 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
72 * @see Mac#getInstance(String)
73 * @see Mac#init(Key)
74 * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_MD5, byte[])}.
75 */
76 @Deprecated
77 public static Mac getHmacMd5(final byte[] key) {
78 return getInitializedMac(HmacAlgorithms.HMAC_MD5, key);
79 }
80
81 /**
82 * Gets an initialized {@link Mac} for the HmacSHA1 algorithm.
83 * <p>
84 * Every implementation of the Java platform is required to support this standard Mac algorithm.
85 * </p>
86 *
87 * @param key The key for the keyed digest (must not be null).
88 * @return A Mac instance initialized with the given key.
89 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
90 * @see Mac#getInstance(String)
91 * @see Mac#init(Key)
92 * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_1, byte[])}.
93 */
94 @Deprecated
95 public static Mac getHmacSha1(final byte[] key) {
96 return getInitializedMac(HmacAlgorithms.HMAC_SHA_1, key);
97 }
98
99 /**
100 * Gets an initialized {@link Mac} for the HmacSHA256 algorithm.
101 * <p>
102 * Every implementation of the Java platform is required to support this standard Mac algorithm.
103 * </p>
104 *
105 * @param key The key for the keyed digest (must not be null).
106 * @return A Mac instance initialized with the given key.
107 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
108 * @see Mac#getInstance(String)
109 * @see Mac#init(Key)
110 * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_256, byte[])}.
111 */
112 @Deprecated
113 public static Mac getHmacSha256(final byte[] key) {
114 return getInitializedMac(HmacAlgorithms.HMAC_SHA_256, key);
115 }
116
117 /**
118 * Gets an initialized {@link Mac} for the HmacSHA384 algorithm.
119 * <p>
120 * Every implementation of the Java platform is <em>not</em> required to support this Mac algorithm.
121 * </p>
122 *
123 * @param key The key for the keyed digest (must not be null).
124 * @return A Mac instance initialized with the given key.
125 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
126 * @see Mac#getInstance(String)
127 * @see Mac#init(Key)
128 * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_384, byte[])}.
129 */
130 @Deprecated
131 public static Mac getHmacSha384(final byte[] key) {
132 return getInitializedMac(HmacAlgorithms.HMAC_SHA_384, key);
133 }
134
135 /**
136 * Gets an initialized {@link Mac} for the HmacSHA512 algorithm.
137 * <p>
138 * Every implementation of the Java platform is <em>not</em> required to support this Mac algorithm.
139 * </p>
140 *
141 * @param key The key for the keyed digest (must not be null).
142 * @return A Mac instance initialized with the given key.
143 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
144 * @see Mac#getInstance(String)
145 * @see Mac#init(Key)
146 * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_512, byte[])}.
147 */
148 @Deprecated
149 public static Mac getHmacSha512(final byte[] key) {
150 return getInitializedMac(HmacAlgorithms.HMAC_SHA_512, key);
151 }
152
153 /**
154 * Gets an initialized {@link Mac} for the given {@code algorithm}.
155 *
156 * @param algorithm The name of the algorithm requested. See
157 * <a href= "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA" >Appendix A in the Java
158 * Cryptography Architecture Reference Guide</a> for information about standard algorithm names.
159 * @param key The key for the keyed digest (must not be null).
160 * @return A Mac instance initialized with the given key.
161 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
162 * @see Mac#getInstance(String)
163 * @see Mac#init(Key)
164 */
165 public static Mac getInitializedMac(final HmacAlgorithms algorithm, final byte[] key) {
166 return getInitializedMac(algorithm.getName(), key);
167 }
168
169 /**
170 * Gets an initialized {@link Mac} for the given {@code algorithm}.
171 *
172 * @param algorithm The name of the algorithm requested. See
173 * <a href= "https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA" >Appendix A in the Java
174 * Cryptography Architecture Reference Guide</a> for information about standard algorithm names.
175 * @param key The key for the keyed digest (must not be null).
176 * @return A Mac instance initialized with the given key.
177 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
178 * @see Mac#getInstance(String)
179 * @see Mac#init(Key)
180 */
181 public static Mac getInitializedMac(final String algorithm, final byte[] key) {
182 if (key == null) {
183 throw new IllegalArgumentException("Null key");
184 }
185 try {
186 final SecretKeySpec keySpec = new SecretKeySpec(key, algorithm);
187 final Mac mac = Mac.getInstance(algorithm);
188 mac.init(keySpec);
189 return mac;
190 } catch (final NoSuchAlgorithmException | InvalidKeyException e) {
191 throw new IllegalArgumentException(e);
192 }
193 }
194
195 /**
196 * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value.
197 *
198 * @param key The key for the keyed digest (must not be null).
199 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
200 * @return HmacMD5 MAC for the given key and value.
201 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
202 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmac(byte[])}.
203 */
204 @Deprecated
205 public static byte[] hmacMd5(final byte[] key, final byte[] valueToDigest) {
206 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmac(valueToDigest);
207 }
208
209 /**
210 * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value.
211 *
212 * @param key The key for the keyed digest (must not be null).
213 * @param valueToDigest The value (data) which should to digest.
214 * The InputStream must not be null and will not be closed.
215 * @return HmacMD5 MAC for the given key and value.
216 * @throws IOException Thrown if an I/O error occurs.
217 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
218 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmac(InputStream)}.
219 */
220 @Deprecated
221 public static byte[] hmacMd5(final byte[] key, final InputStream valueToDigest) throws IOException {
222 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmac(valueToDigest);
223 }
224
225 /**
226 * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value.
227 *
228 * @param key The key for the keyed digest (must not be null).
229 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
230 * @return HmacMD5 MAC for the given key and value.
231 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
232 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, String).hmac(String)}.
233 */
234 @Deprecated
235 public static byte[] hmacMd5(final String key, final String valueToDigest) {
236 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmac(valueToDigest);
237 }
238
239 /**
240 * Returns a HmacMD5 Message Authentication Code (MAC) as a hexadecimal string (lowercase) for the given key and value.
241 *
242 * @param key The key for the keyed digest (must not be null).
243 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
244 * @return HmacMD5 MAC for the given key and value as a hexadecimal string (lowercase).
245 * @throws IllegalArgumentException Thrown if 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[]).hmacHex(byte[])}.
247 */
248 @Deprecated
249 public static String hmacMd5Hex(final byte[] key, final byte[] valueToDigest) {
250 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(valueToDigest);
251 }
252
253 /**
254 * Returns a HmacMD5 Message Authentication Code (MAC) as a hexadecimal string (lowercase) for the given key and value.
255 *
256 * @param key The key for the keyed digest (must not be null).
257 * @param valueToDigest The value (data) which should to digest.
258 * The InputStream must not be null and will not be closed.
259 * @return HmacMD5 MAC for the given key and value as a hexadecimal string (lowercase).
260 * @throws IOException Thrown if an I/O error occurs.
261 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
262 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmacHex(InputStream)}.
263 */
264 @Deprecated
265 public static String hmacMd5Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
266 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(valueToDigest);
267 }
268
269 /**
270 * Returns a HmacMD5 Message Authentication Code (MAC) as a hexadecimal string (lowercase) for the given key and value.
271 *
272 * @param key The key for the keyed digest (must not be null).
273 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
274 * @return HmacMD5 MAC for the given key and value as a hexadecimal string (lowercase).
275 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
276 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, String).hmacHex(String)}.
277 */
278 @Deprecated
279 public static String hmacMd5Hex(final String key, final String valueToDigest) {
280 return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(valueToDigest);
281 }
282
283 /**
284 * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value.
285 *
286 * @param key The key for the keyed digest (must not be null).
287 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
288 * @return HmacSHA1 MAC for the given key and value.
289 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
290 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmac(byte[])}.
291 */
292 @Deprecated
293 public static byte[] hmacSha1(final byte[] key, final byte[] valueToDigest) {
294 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmac(valueToDigest);
295 }
296
297 /**
298 * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value.
299 *
300 * @param key The key for the keyed digest (must not be null).
301 * @param valueToDigest The value (data) which should to digest.
302 * The InputStream must not be null and will not be closed.
303 * @return HmacSHA1 MAC for the given key and value.
304 * @throws IOException Thrown if an I/O error occurs.
305 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
306 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmac(InputStream)}.
307 */
308 @Deprecated
309 public static byte[] hmacSha1(final byte[] key, final InputStream valueToDigest) throws IOException {
310 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmac(valueToDigest);
311 }
312
313 /**
314 * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value.
315 *
316 * @param key The key for the keyed digest (must not be null).
317 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
318 * @return HmacSHA1 MAC for the given key and value.
319 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
320 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, String).hmac(String)}.
321 */
322 @Deprecated
323 public static byte[] hmacSha1(final String key, final String valueToDigest) {
324 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmac(valueToDigest);
325 }
326
327 /**
328 * Returns a HmacSHA1 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
329 *
330 * @param key The key for the keyed digest (must not be null).
331 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
332 * @return HmacSHA1 MAC for the given key and value as hexadecimal string (lowercase).
333 * @throws IllegalArgumentException Thrown if 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[]).hmacHex(byte[])}
335 */
336 @Deprecated
337 public static String hmacSha1Hex(final byte[] key, final byte[] valueToDigest) {
338 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(valueToDigest);
339 }
340
341 /**
342 * Returns a HmacSHA1 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
343 *
344 * @param key The key for the keyed digest (must not be null).
345 * @param valueToDigest The value (data) which should to digest.
346 * The InputStream must not be null and will not be closed.
347 * @return HmacSHA1 MAC for the given key and value as hexadecimal string (lowercase).
348 * @throws IOException Thrown if an I/O error occurs.
349 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
350 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmacHex(InputStream)}.
351 */
352 @Deprecated
353 public static String hmacSha1Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
354 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(valueToDigest);
355 }
356
357 /**
358 * Returns a HmacSHA1 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
359 *
360 * @param key The key for the keyed digest (must not be null).
361 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
362 * @return HmacSHA1 MAC for the given key and value as hexadecimal string (lowercase).
363 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
364 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, String).hmacHex(String)}.
365 */
366 @Deprecated
367 public static String hmacSha1Hex(final String key, final String valueToDigest) {
368 return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(valueToDigest);
369 }
370
371 /**
372 * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value.
373 *
374 * @param key The key for the keyed digest (must not be null).
375 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
376 * @return HmacSHA256 MAC for the given key and value.
377 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
378 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmac(byte[])}.
379 */
380 @Deprecated
381 public static byte[] hmacSha256(final byte[] key, final byte[] valueToDigest) {
382 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(valueToDigest);
383 }
384
385 /**
386 * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value.
387 *
388 * @param key The key for the keyed digest (must not be null).
389 * @param valueToDigest The value (data) which should to digest. The InputStream must not be null and will not be closed.
390 * @return HmacSHA256 MAC for the given key and value.
391 * @throws IOException Thrown if an I/O error occurs.
392 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
393 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmac(InputStream)}.
394 */
395 @Deprecated
396 public static byte[] hmacSha256(final byte[] key, final InputStream valueToDigest) throws IOException {
397 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(valueToDigest);
398 }
399
400 /**
401 * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value.
402 *
403 * @param key The key for the keyed digest (must not be null).
404 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
405 * @return HmacSHA256 MAC for the given key and value.
406 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
407 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, String).hmac(String)}.
408 */
409 @Deprecated
410 public static byte[] hmacSha256(final String key, final String valueToDigest) {
411 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(valueToDigest);
412 }
413
414 /**
415 * Returns a HmacSHA256 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
416 *
417 * @param key The key for the keyed digest (must not be null).
418 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
419 * @return HmacSHA256 MAC for the given key and value as hexadecimal string (lowercase).
420 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
421 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmacHex(byte[])}.
422 */
423 @Deprecated
424 public static String hmacSha256Hex(final byte[] key, final byte[] valueToDigest) {
425 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest);
426 }
427
428 /**
429 * Returns a HmacSHA256 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
430 *
431 * @param key The key for the keyed digest (must not be null).
432 * @param valueToDigest The value (data) which should to digest.
433 * The InputStream must not be null and will not be closed.
434 * @return HmacSHA256 MAC for the given key and value as hexadecimal string (lowercase).
435 * @throws IOException Thrown if an I/O error occurs.
436 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
437 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmacHex(InputStream)}.
438 */
439 @Deprecated
440 public static String hmacSha256Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
441 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest);
442 }
443
444 /**
445 * Returns a HmacSHA256 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
446 *
447 * @param key The key for the keyed digest (must not be null).
448 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
449 * @return HmacSHA256 MAC for the given key and value as hexadecimal string (lowercase).
450 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
451 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, String).hmacHex(String)}.
452 */
453 @Deprecated
454 public static String hmacSha256Hex(final String key, final String valueToDigest) {
455 return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest);
456 }
457
458 /**
459 * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value.
460 *
461 * @param key The key for the keyed digest (must not be null).
462 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
463 * @return HmacSHA384 MAC for the given key and value.
464 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
465 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmac(byte[])}.
466 */
467 @Deprecated
468 public static byte[] hmacSha384(final byte[] key, final byte[] valueToDigest) {
469 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest);
470 }
471
472 /**
473 * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value.
474 *
475 * @param key The key for the keyed digest (must not be null).
476 * @param valueToDigest The value (data) which should to digest.
477 * The InputStream must not be null and will not be closed.
478 * @return HmacSHA384 MAC for the given key and value.
479 * @throws IOException Thrown if an I/O error occurs.
480 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
481 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmac(InputStream)}.
482 */
483 @Deprecated
484 public static byte[] hmacSha384(final byte[] key, final InputStream valueToDigest) throws IOException {
485 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest);
486 }
487
488 /**
489 * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value.
490 *
491 * @param key The key for the keyed digest (must not be null).
492 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
493 * @return HmacSHA384 MAC for the given key and value.
494 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
495 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, String).hmac(String)}.
496 */
497 @Deprecated
498 public static byte[] hmacSha384(final String key, final String valueToDigest) {
499 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest);
500 }
501 // hmacSha384
502
503 /**
504 * Returns a HmacSHA384 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
505 *
506 * @param key The key for the keyed digest (must not be null).
507 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
508 * @return HmacSHA384 MAC for the given key and value as hexadecimal string (lowercase).
509 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
510 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmacHex(byte[])}.
511 */
512 @Deprecated
513 public static String hmacSha384Hex(final byte[] key, final byte[] valueToDigest) {
514 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest);
515 }
516
517 /**
518 * Returns a HmacSHA384 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
519 *
520 * @param key The key for the keyed digest (must not be null).
521 * @param valueToDigest The value (data) which should to digest.
522 * The InputStream must not be null and will not be closed.
523 * @return HmacSHA384 MAC for the given key and value as hexadecimal string (lowercase).
524 * @throws IOException Thrown if an I/O error occurs.
525 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
526 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmacHex(InputStream)}.
527 */
528 @Deprecated
529 public static String hmacSha384Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
530 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest);
531 }
532
533 /**
534 * Returns a HmacSHA384 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
535 *
536 * @param key The key for the keyed digest (must not be null).
537 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
538 * @return HmacSHA384 MAC for the given key and value as hexadecimal string (lowercase).
539 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
540 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, String).hmacHex(String)}.
541 */
542 @Deprecated
543 public static String hmacSha384Hex(final String key, final String valueToDigest) {
544 return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest);
545 }
546
547 /**
548 * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value.
549 *
550 * @param key The key for the keyed digest (must not be null).
551 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
552 * @return HmacSHA512 MAC for the given key and value.
553 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
554 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmac(byte[])}.
555 */
556 @Deprecated
557 public static byte[] hmacSha512(final byte[] key, final byte[] valueToDigest) {
558 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest);
559 }
560
561 /**
562 * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value.
563 *
564 * @param key The key for the keyed digest (must not be null).
565 * @param valueToDigest The value (data) which should to digest.
566 * The InputStream must not be null and will not be closed.
567 * @return HmacSHA512 MAC for the given key and value.
568 * @throws IOException Thrown if an I/O error occurs.
569 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
570 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmac(InputStream)}.
571 */
572 @Deprecated
573 public static byte[] hmacSha512(final byte[] key, final InputStream valueToDigest) throws IOException {
574 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest);
575 }
576
577 /**
578 * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value.
579 *
580 * @param key The key for the keyed digest (must not be null).
581 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
582 * @return HmacSHA512 MAC for the given key and value.
583 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
584 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, String).hmac(String)}.
585 */
586 @Deprecated
587 public static byte[] hmacSha512(final String key, final String valueToDigest) {
588 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest);
589 }
590 // hmacSha512
591
592 /**
593 * Returns a HmacSHA512 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
594 *
595 * @param key The key for the keyed digest (must not be null).
596 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
597 * @return HmacSHA512 MAC for the given key and value as hexadecimal string (lowercase).
598 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
599 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmacHex(byte[])}.
600 */
601 @Deprecated
602 public static String hmacSha512Hex(final byte[] key, final byte[] valueToDigest) {
603 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest);
604 }
605
606 /**
607 * Returns a HmacSHA512 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
608 *
609 * @param key The key for the keyed digest (must not be null).
610 * @param valueToDigest The value (data) which should to digest.
611 * The InputStream must not be null and will not be closed.
612 * @return HmacSHA512 MAC for the given key and value as hexadecimal string (lowercase).
613 * @throws IOException Thrown if an I/O error occurs.
614 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
615 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmacHex(InputStream)}.
616 */
617 @Deprecated
618 public static String hmacSha512Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
619 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest);
620 }
621
622 /**
623 * Returns a HmacSHA512 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
624 *
625 * @param key The key for the keyed digest (must not be null).
626 * @param valueToDigest The value (data) which should to digest (maybe empty or null).
627 * @return HmacSHA512 MAC for the given key and value as hexadecimal string (lowercase).
628 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
629 * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, String).hmacHex(String)}.
630 */
631 @Deprecated
632 public static String hmacSha512Hex(final String key, final String valueToDigest) {
633 return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest);
634 }
635
636 /**
637 * Tests whether this algorithm is available.
638 *
639 * @param hmacAlgorithms The HmacAlgorithms to check.
640 * @return whether this algorithm is available.
641 * @since 1.11
642 */
643 public static boolean isAvailable(final HmacAlgorithms hmacAlgorithms) {
644 return isAvailable(hmacAlgorithms.getName());
645 }
646
647 /**
648 * Tests whether this algorithm is available.
649 *
650 * @param name The name to check.
651 * @return whether this algorithm is available.
652 * @since 1.11
653 */
654 public static boolean isAvailable(final String name) {
655 try {
656 Mac.getInstance(name);
657 return true;
658 } catch (final NoSuchAlgorithmException e) {
659 return false;
660 }
661 }
662
663 /**
664 * Resets and then updates the given {@link Mac} with the value.
665 *
666 * @param mac The initialized {@link Mac} to update.
667 * @param valueToDigest The value to update the {@link Mac} with (maybe null or empty).
668 * @return The updated {@link Mac}.
669 * @throws IllegalStateException Thrown if the Mac was not initialized.
670 */
671 public static Mac updateHmac(final Mac mac, final byte[] valueToDigest) {
672 mac.reset();
673 mac.update(valueToDigest);
674 return mac;
675 }
676
677 /**
678 * Resets and then updates the given {@link Mac} with the value.
679 *
680 * @param mac The initialized {@link Mac} to update.
681 * @param valueToDigest The value to update the {@link Mac} with.
682 * The InputStream must not be null and will not be closed.
683 * @return The updated {@link Mac}.
684 * @throws IOException Thrown if an I/O error occurs.
685 * @throws IllegalStateException Thrown if the Mac was not initialized.
686 */
687 public static Mac updateHmac(final Mac mac, final InputStream valueToDigest) throws IOException {
688 mac.reset();
689 final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
690 int read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH);
691 while (read > -1) {
692 mac.update(buffer, 0, read);
693 read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH);
694 }
695 return mac;
696 }
697
698 /**
699 * Resets and then updates the given {@link Mac} with the value.
700 *
701 * @param mac The initialized {@link Mac} to update.
702 * @param valueToDigest The value to update the {@link Mac} with (maybe null or empty).
703 * @return The updated {@link Mac}.
704 * @throws IllegalStateException Thrown if the Mac was not initialized.
705 */
706 public static Mac updateHmac(final Mac mac, final String valueToDigest) {
707 mac.reset();
708 mac.update(StringUtils.getBytesUtf8(valueToDigest));
709 return mac;
710 }
711
712 private final Mac mac;
713
714 /**
715 * Preserves binary compatibility only. As for previous versions does not provide useful behavior.
716 *
717 * @deprecated Since 1.11; only useful to preserve binary compatibility.
718 */
719 @Deprecated
720 public HmacUtils() {
721 this(null);
722 }
723
724 /**
725 * Creates an instance using the provided algorithm type.
726 *
727 * @param algorithm to use.
728 * @param key The key to use.
729 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
730 * @since 1.11
731 */
732 public HmacUtils(final HmacAlgorithms algorithm, final byte[] key) {
733 this(algorithm.getName(), key);
734 }
735
736 /**
737 * Creates an instance using the provided algorithm type.
738 *
739 * @param algorithm to use.
740 * @param key The key to use.
741 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
742 * @since 1.11
743 */
744 public HmacUtils(final HmacAlgorithms algorithm, final String key) {
745 this(algorithm.getName(), StringUtils.getBytesUtf8(key));
746 }
747
748 private HmacUtils(final Mac mac) {
749 this.mac = mac;
750 }
751
752 /**
753 * Creates an instance using the provided algorithm type.
754 *
755 * @param algorithm to use.
756 * @param key The key to use.
757 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
758 * @since 1.11
759 */
760 public HmacUtils(final String algorithm, final byte[] key) {
761 this(getInitializedMac(algorithm, key));
762 }
763
764 /**
765 * Creates an instance using the provided algorithm type.
766 *
767 * @param algorithm to use.
768 * @param key The key to use.
769 * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
770 * @since 1.11
771 */
772 public HmacUtils(final String algorithm, final String key) {
773 this(algorithm, StringUtils.getBytesUtf8(key));
774 }
775
776 /**
777 * Returns the digest for the input data.
778 *
779 * @param valueToDigest The input to use.
780 * @return The digest as a byte[].
781 * @since 1.11
782 */
783 public byte[] hmac(final byte[] valueToDigest) {
784 return mac.doFinal(valueToDigest);
785 }
786
787 /**
788 * Returns the digest for the input data.
789 *
790 * @param valueToDigest The input to use.
791 * @return The digest as a byte[].
792 * @since 1.11
793 */
794 public byte[] hmac(final ByteBuffer valueToDigest) {
795 mac.update(valueToDigest);
796 return mac.doFinal();
797 }
798
799 /**
800 * Returns the digest for the file.
801 *
802 * @param valueToDigest The file to use.
803 * @return The digest.
804 * @throws IOException Thrown if an I/O error occurs.
805 * @since 1.11
806 */
807 public byte[] hmac(final File valueToDigest) throws IOException {
808 return hmac(valueToDigest.toPath());
809 }
810
811 /**
812 * Returns the digest for the stream.
813 *
814 * @param valueToDigest The data to use.
815 * The InputStream must not be null and will not be closed.
816 * @return The digest.
817 * @throws IOException Thrown if an I/O error occurs.
818 * @since 1.11
819 */
820 public byte[] hmac(final InputStream valueToDigest) throws IOException {
821 final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
822 int read;
823 while ((read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH)) > -1) {
824 mac.update(buffer, 0, read);
825 }
826 return mac.doFinal();
827 }
828
829 /**
830 * Returns the digest for the file.
831 *
832 * @param valueToDigest The path to use.
833 * @return The digest.
834 * @throws IOException Thrown if an I/O error occurs.
835 * @since 1.19.0
836 */
837 public byte[] hmac(final Path valueToDigest) throws IOException {
838 try (BufferedInputStream stream = new BufferedInputStream(Files.newInputStream(valueToDigest))) {
839 return hmac(stream);
840 }
841 }
842
843 /**
844 * Returns the digest for the input data.
845 *
846 * @param valueToDigest The input to use, treated as UTF-8.
847 * @return The digest as a byte[].
848 * @since 1.11
849 */
850 public byte[] hmac(final String valueToDigest) {
851 return mac.doFinal(StringUtils.getBytesUtf8(valueToDigest));
852 }
853
854 /**
855 * Returns the digest for the input data.
856 *
857 * @param valueToDigest The input to use.
858 * @return The digest as a hexadecimal String.
859 * @since 1.11
860 */
861 public String hmacHex(final byte[] valueToDigest) {
862 return Hex.encodeHexString(hmac(valueToDigest));
863 }
864
865 /**
866 * Returns the digest for the input data.
867 *
868 * @param valueToDigest The input to use.
869 * @return The digest as a hexadecimal String.
870 * @since 1.11
871 */
872 public String hmacHex(final ByteBuffer valueToDigest) {
873 return Hex.encodeHexString(hmac(valueToDigest));
874 }
875
876 /**
877 * Returns the digest for the file.
878 *
879 * @param valueToDigest The file to use.
880 * @return The digest as a hexadecimal String.
881 * @throws IOException Thrown if an I/O error occurs.
882 * @since 1.11
883 */
884 public String hmacHex(final File valueToDigest) throws IOException {
885 return Hex.encodeHexString(hmac(valueToDigest));
886 }
887
888 /**
889 * Returns the digest for the stream.
890 *
891 * @param valueToDigest The data to use.
892 * The InputStream must not be null and will not be closed.
893 * @return The digest as a hexadecimal String.
894 * @throws IOException Thrown if an I/O error occurs.
895 * @since 1.11
896 */
897 public String hmacHex(final InputStream valueToDigest) throws IOException {
898 return Hex.encodeHexString(hmac(valueToDigest));
899 }
900
901 /**
902 * Returns the digest for the path.
903 *
904 * @param valueToDigest The path to use.
905 * @return The digest as a hexadecimal String.
906 * @throws IOException Thrown if an I/O error occurs.
907 * @since 1.19.0
908 */
909 public String hmacHex(final Path valueToDigest) throws IOException {
910 return Hex.encodeHexString(hmac(valueToDigest));
911 }
912
913 /**
914 * Returns the digest for the input data.
915 *
916 * @param valueToDigest The input to use, treated as UTF-8.
917 * @return The digest as a hexadecimal String.
918 * @since 1.11
919 */
920 public String hmacHex(final String valueToDigest) {
921 return Hex.encodeHexString(hmac(valueToDigest));
922 }
923 }