Source code
Description: source: package: org.apache.commons.codec.digest, class: HmacUtils

    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      https://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017
    018package org.apache.commons.codec.digest;
    019
    020import java.io.BufferedInputStream;
    021import java.io.File;
    022import java.io.IOException;
    023import java.io.InputStream;
    024import java.nio.ByteBuffer;
    025import java.nio.file.Files;
    026import java.nio.file.Path;
    027import java.security.InvalidKeyException;
    028import java.security.Key;
    029import java.security.NoSuchAlgorithmException;
    030
    031import javax.crypto.Mac;
    032import javax.crypto.spec.SecretKeySpec;
    033
    034import org.apache.commons.codec.binary.Hex;
    035import org.apache.commons.codec.binary.StringUtils;
    036
    037/**
    038 * Simplifies common {@link Mac} tasks. This class is immutable and thread-safe. However the Mac may not be.
    039 * <p>
    040 * <strong>Note: Not all JCE implementations support all algorithms. If not supported, an IllegalArgumentException is thrown.</strong>
    041 * </p>
    042 * <p>
    043 * Sample usage:
    044 * </p>
    045 *
    046 * <pre>
    047 * import static HmacAlgorithms.*;
    048 * byte[] key = {1,2,3,4}; // don't use this actual key!
    049 * String valueToDigest = "The quick brown fox jumps over the lazy dog";
    050 * byte[] hmac = new HmacUtils(HMAC_SHA_224, key).hmac(valueToDigest);
    051 * // Mac reuse
    052 * HmacUtils hm1 = new HmacUtils("HmacAlgoName", key); // use a valid name here!
    053 * String hexPom = hm1.hmacHex(new File("pom.xml"));
    054 * String hexNot = hm1.hmacHex(new File("NOTICE.txt"));
    055 * </pre>
    056 *
    057 * @since 1.10
    058 */
    059public final class HmacUtils {
    060
    061    private static final int STREAM_BUFFER_LENGTH = 1024;
    062
    063    /**
    064     * Returns an initialized {@link Mac} for the HmacMD5 algorithm.
    065     * <p>
    066     * Every implementation of the Java platform is required to support this standard Mac algorithm.
    067     * </p>
    068     *
    069     * @param key The key for the keyed digest (must not be null).
    070     * @return A Mac instance initialized with the given key.
    071     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    072     * @see Mac#getInstance(String)
    073     * @see Mac#init(Key)
    074     * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_MD5, byte[])}.
    075     */
    076    @Deprecated
    077    public static Mac getHmacMd5(final byte[] key) {
    078        return getInitializedMac(HmacAlgorithms.HMAC_MD5, key);
    079    }
    080
    081    /**
    082     * Returns an initialized {@link Mac} for the HmacSHA1 algorithm.
    083     * <p>
    084     * Every implementation of the Java platform is required to support this standard Mac algorithm.
    085     * </p>
    086     *
    087     * @param key The key for the keyed digest (must not be null).
    088     * @return A Mac instance initialized with the given key.
    089     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    090     * @see Mac#getInstance(String)
    091     * @see Mac#init(Key)
    092     * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_1, byte[])}.
    093     */
    094    @Deprecated
    095    public static Mac getHmacSha1(final byte[] key) {
    096        return getInitializedMac(HmacAlgorithms.HMAC_SHA_1, key);
    097    }
    098
    099    /**
    100     * Returns 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     * Returns 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     * Returns 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     * Returns 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     * Returns 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              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              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              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              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     *                      <p>
    434     *                      The InputStream must not be null and will not be closed.
    435     *                      </p>
    436     * @return HmacSHA256 MAC for the given key and value as hexadecimal string (lowercase).
    437     * @throws IOException              If an I/O error occurs.
    438     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    439     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmacHex(InputStream)}.
    440     */
    441    @Deprecated
    442    public static String hmacSha256Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
    443        return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest);
    444    }
    445
    446    /**
    447     * Returns a HmacSHA256 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
    448     *
    449     * @param key           The key for the keyed digest (must not be null).
    450     * @param valueToDigest The value (data) which should to digest (maybe empty or null).
    451     * @return HmacSHA256 MAC for the given key and value as hexadecimal string (lowercase).
    452     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    453     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, String).hmacHex(String)}.
    454     */
    455    @Deprecated
    456    public static String hmacSha256Hex(final String key, final String valueToDigest) {
    457        return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest);
    458    }
    459
    460    /**
    461     * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value.
    462     *
    463     * @param key           The key for the keyed digest (must not be null).
    464     * @param valueToDigest The value (data) which should to digest (maybe empty or null).
    465     * @return HmacSHA384 MAC for the given key and value.
    466     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    467     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmac(byte[])}.
    468     */
    469    @Deprecated
    470    public static byte[] hmacSha384(final byte[] key, final byte[] valueToDigest) {
    471        return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest);
    472    }
    473
    474    /**
    475     * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value.
    476     *
    477     * @param key           The key for the keyed digest (must not be null).
    478     * @param valueToDigest The value (data) which should to digest.
    479     *                      <p>
    480     *                      The InputStream must not be null and will not be closed.
    481     *                      </p>
    482     * @return HmacSHA384 MAC for the given key and value.
    483     * @throws IOException              If an I/O error occurs.
    484     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    485     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmac(InputStream)}.
    486     */
    487    @Deprecated
    488    public static byte[] hmacSha384(final byte[] key, final InputStream valueToDigest) throws IOException {
    489        return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest);
    490    }
    491
    492    /**
    493     * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value.
    494     *
    495     * @param key           The key for the keyed digest (must not be null).
    496     * @param valueToDigest The value (data) which should to digest (maybe empty or null).
    497     * @return HmacSHA384 MAC for the given key and value.
    498     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    499     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, String).hmac(String)}.
    500     */
    501    @Deprecated
    502    public static byte[] hmacSha384(final String key, final String valueToDigest) {
    503        return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest);
    504    }
    505    // hmacSha384
    506
    507    /**
    508     * Returns a HmacSHA384 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
    509     *
    510     * @param key           The key for the keyed digest (must not be null).
    511     * @param valueToDigest The value (data) which should to digest (maybe empty or null).
    512     * @return HmacSHA384 MAC for the given key and value as hexadecimal string (lowercase).
    513     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    514     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmacHex(byte[])}.
    515     */
    516    @Deprecated
    517    public static String hmacSha384Hex(final byte[] key, final byte[] valueToDigest) {
    518        return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest);
    519    }
    520
    521    /**
    522     * Returns a HmacSHA384 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
    523     *
    524     * @param key           The key for the keyed digest (must not be null).
    525     * @param valueToDigest The value (data) which should to digest.
    526     *                      <p>
    527     *                      The InputStream must not be null and will not be closed.
    528     *                      </p>
    529     * @return HmacSHA384 MAC for the given key and value as hexadecimal string (lowercase).
    530     * @throws IOException              If an I/O error occurs.
    531     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    532     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmacHex(InputStream)}.
    533     */
    534    @Deprecated
    535    public static String hmacSha384Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
    536        return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest);
    537    }
    538
    539    /**
    540     * Returns a HmacSHA384 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
    541     *
    542     * @param key           The key for the keyed digest (must not be null).
    543     * @param valueToDigest The value (data) which should to digest (maybe empty or null).
    544     * @return HmacSHA384 MAC for the given key and value as hexadecimal string (lowercase).
    545     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    546     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, String).hmacHex(String)}.
    547     */
    548    @Deprecated
    549    public static String hmacSha384Hex(final String key, final String valueToDigest) {
    550        return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest);
    551    }
    552
    553    /**
    554     * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value.
    555     *
    556     * @param key           The key for the keyed digest (must not be null).
    557     * @param valueToDigest The value (data) which should to digest (maybe empty or null).
    558     * @return HmacSHA512 MAC for the given key and value.
    559     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    560     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmac(byte[])}.
    561     */
    562    @Deprecated
    563    public static byte[] hmacSha512(final byte[] key, final byte[] valueToDigest) {
    564        return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest);
    565    }
    566
    567    /**
    568     * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value.
    569     *
    570     * @param key           The key for the keyed digest (must not be null).
    571     * @param valueToDigest The value (data) which should to digest.
    572     *                      <p>
    573     *                      The InputStream must not be null and will not be closed.
    574     *                      </p>
    575     * @return HmacSHA512 MAC for the given key and value.
    576     * @throws IOException              If an I/O error occurs.
    577     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    578     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmac(InputStream)}.
    579     */
    580    @Deprecated
    581    public static byte[] hmacSha512(final byte[] key, final InputStream valueToDigest) throws IOException {
    582        return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest);
    583    }
    584
    585    /**
    586     * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value.
    587     *
    588     * @param key           The key for the keyed digest (must not be null).
    589     * @param valueToDigest The value (data) which should to digest (maybe empty or null).
    590     * @return HmacSHA512 MAC for the given key and value.
    591     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    592     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, String).hmac(String)}.
    593     */
    594    @Deprecated
    595    public static byte[] hmacSha512(final String key, final String valueToDigest) {
    596        return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest);
    597    }
    598    // hmacSha512
    599
    600    /**
    601     * Returns a HmacSHA512 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
    602     *
    603     * @param key           The key for the keyed digest (must not be null).
    604     * @param valueToDigest The value (data) which should to digest (maybe empty or null).
    605     * @return HmacSHA512 MAC for the given key and value as hexadecimal string (lowercase).
    606     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    607     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmacHex(byte[])}.
    608     */
    609    @Deprecated
    610    public static String hmacSha512Hex(final byte[] key, final byte[] valueToDigest) {
    611        return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest);
    612    }
    613
    614    /**
    615     * Returns a HmacSHA512 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
    616     *
    617     * @param key           The key for the keyed digest (must not be null).
    618     * @param valueToDigest The value (data) which should to digest.
    619     *                      <p>
    620     *                      The InputStream must not be null and will not be closed.
    621     *                      </p>
    622     * @return HmacSHA512 MAC for the given key and value as hexadecimal string (lowercase).
    623     * @throws IOException              If an I/O error occurs.
    624     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    625     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmacHex(InputStream)}.
    626     */
    627    @Deprecated
    628    public static String hmacSha512Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
    629        return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest);
    630    }
    631
    632    /**
    633     * Returns a HmacSHA512 Message Authentication Code (MAC) as hexadecimal string (lowercase) for the given key and value.
    634     *
    635     * @param key           The key for the keyed digest (must not be null).
    636     * @param valueToDigest The value (data) which should to digest (maybe empty or null).
    637     * @return HmacSHA512 MAC for the given key and value as hexadecimal string (lowercase).
    638     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    639     * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, String).hmacHex(String)}.
    640     */
    641    @Deprecated
    642    public static String hmacSha512Hex(final String key, final String valueToDigest) {
    643        return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest);
    644    }
    645
    646    /**
    647     * Tests whether this algorithm is available
    648     *
    649     * @param hmacAlgorithms The HmacAlgorithms to check.
    650     * @return whether this algorithm is available.
    651     * @since 1.11
    652     */
    653    public static boolean isAvailable(final HmacAlgorithms hmacAlgorithms) {
    654        return isAvailable(hmacAlgorithms.getName());
    655    }
    656
    657    /**
    658     * Tests whether this algorithm is available
    659     *
    660     * @param name The name to check.
    661     * @return whether this algorithm is available.
    662     * @since 1.11
    663     */
    664    public static boolean isAvailable(final String name) {
    665        try {
    666            Mac.getInstance(name);
    667            return true;
    668        } catch (final NoSuchAlgorithmException e) {
    669            return false;
    670        }
    671    }
    672
    673    /**
    674     * Resets and then updates the given {@link Mac} with the value.
    675     *
    676     * @param mac           The initialized {@link Mac} to update.
    677     * @param valueToDigest The value to update the {@link Mac} with (maybe null or empty).
    678     * @return The updated {@link Mac}.
    679     * @throws IllegalStateException if the Mac was not initialized.
    680     */
    681    public static Mac updateHmac(final Mac mac, final byte[] valueToDigest) {
    682        mac.reset();
    683        mac.update(valueToDigest);
    684        return mac;
    685    }
    686
    687    /**
    688     * Resets and then updates the given {@link Mac} with the value.
    689     *
    690     * @param mac           The initialized {@link Mac} to update.
    691     * @param valueToDigest The value to update the {@link Mac} with.
    692     *                      <p>
    693     *                      The InputStream must not be null and will not be closed.
    694     *                      </p>
    695     * @return The updated {@link Mac}.
    696     * @throws IOException           If an I/O error occurs.
    697     * @throws IllegalStateException If the Mac was not initialized.
    698     */
    699    public static Mac updateHmac(final Mac mac, final InputStream valueToDigest) throws IOException {
    700        mac.reset();
    701        final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
    702        int read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH);
    703        while (read > -1) {
    704            mac.update(buffer, 0, read);
    705            read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH);
    706        }
    707        return mac;
    708    }
    709
    710    /**
    711     * Resets and then updates the given {@link Mac} with the value.
    712     *
    713     * @param mac           The initialized {@link Mac} to update.
    714     * @param valueToDigest The value to update the {@link Mac} with (maybe null or empty).
    715     * @return The updated {@link Mac}.
    716     * @throws IllegalStateException if the Mac was not initialized.
    717     */
    718    public static Mac updateHmac(final Mac mac, final String valueToDigest) {
    719        mac.reset();
    720        mac.update(StringUtils.getBytesUtf8(valueToDigest));
    721        return mac;
    722    }
    723
    724    private final Mac mac;
    725
    726    /**
    727     * Preserves binary compatibility only. As for previous versions does not provide useful behavior.
    728     *
    729     * @deprecated Since 1.11; only useful to preserve binary compatibility.
    730     */
    731    @Deprecated
    732    public HmacUtils() {
    733        this(null);
    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 byte[] key) {
    745        this(algorithm.getName(), key);
    746    }
    747
    748    /**
    749     * Creates an instance using the provided algorithm type.
    750     *
    751     * @param algorithm to use.
    752     * @param key       The key to use.
    753     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    754     * @since 1.11
    755     */
    756    public HmacUtils(final HmacAlgorithms algorithm, final String key) {
    757        this(algorithm.getName(), StringUtils.getBytesUtf8(key));
    758    }
    759
    760    private HmacUtils(final Mac mac) {
    761        this.mac = mac;
    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 byte[] key) {
    773        this(getInitializedMac(algorithm, key));
    774    }
    775
    776    /**
    777     * Creates an instance using the provided algorithm type.
    778     *
    779     * @param algorithm to use.
    780     * @param key       The key to use.
    781     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
    782     * @since 1.11
    783     */
    784    public HmacUtils(final String algorithm, final String key) {
    785        this(algorithm, StringUtils.getBytesUtf8(key));
    786    }
    787
    788    /**
    789     * Returns the digest for the input data.
    790     *
    791     * @param valueToDigest The input to use.
    792     * @return The digest as a byte[].
    793     * @since 1.11
    794     */
    795    public byte[] hmac(final byte[] valueToDigest) {
    796        return mac.doFinal(valueToDigest);
    797    }
    798
    799    /**
    800     * Returns the digest for the input data.
    801     *
    802     * @param valueToDigest The input to use.
    803     * @return The digest as a byte[].
    804     * @since 1.11
    805     */
    806    public byte[] hmac(final ByteBuffer valueToDigest) {
    807        mac.update(valueToDigest);
    808        return mac.doFinal();
    809    }
    810
    811    /**
    812     * Returns the digest for the file.
    813     *
    814     * @param valueToDigest The file to use.
    815     * @return The digest.
    816     * @throws IOException If an I/O error occurs.
    817     * @since 1.11
    818     */
    819    public byte[] hmac(final File valueToDigest) throws IOException {
    820        return hmac(valueToDigest.toPath());
    821    }
    822
    823    /**
    824     * Returns the digest for the stream.
    825     *
    826     * @param valueToDigest The data to use.
    827     *                      <p>
    828     *                      The InputStream must not be null and will not be closed.
    829     *                      </p>
    830     * @return The digest.
    831     * @throws IOException If an I/O error occurs.
    832     * @since 1.11
    833     */
    834    public byte[] hmac(final InputStream valueToDigest) throws IOException {
    835        final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
    836        int read;
    837        while ((read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH)) > -1) {
    838            mac.update(buffer, 0, read);
    839        }
    840        return mac.doFinal();
    841    }
    842
    843    /**
    844     * Returns the digest for the file.
    845     *
    846     * @param valueToDigest The path to use.
    847     * @return The digest.
    848     * @throws IOException If an I/O error occurs.
    849     * @since 1.19.0
    850     */
    851    public byte[] hmac(final Path valueToDigest) throws IOException {
    852        try (BufferedInputStream stream = new BufferedInputStream(Files.newInputStream(valueToDigest))) {
    853            return hmac(stream);
    854        }
    855    }
    856
    857    /**
    858     * Returns the digest for the input data.
    859     *
    860     * @param valueToDigest The input to use, treated as UTF-8.
    861     * @return The digest as a byte[].
    862     * @since 1.11
    863     */
    864    public byte[] hmac(final String valueToDigest) {
    865        return mac.doFinal(StringUtils.getBytesUtf8(valueToDigest));
    866    }
    867
    868    /**
    869     * Returns the digest for the input data.
    870     *
    871     * @param valueToDigest The input to use.
    872     * @return The digest as a hexadecimal String.
    873     * @since 1.11
    874     */
    875    public String hmacHex(final byte[] valueToDigest) {
    876        return Hex.encodeHexString(hmac(valueToDigest));
    877    }
    878
    879    /**
    880     * Returns the digest for the input data.
    881     *
    882     * @param valueToDigest The input to use.
    883     * @return The digest as a hexadecimal String.
    884     * @since 1.11
    885     */
    886    public String hmacHex(final ByteBuffer valueToDigest) {
    887        return Hex.encodeHexString(hmac(valueToDigest));
    888    }
    889
    890    /**
    891     * Returns the digest for the file.
    892     *
    893     * @param valueToDigest The file to use.
    894     * @return The digest as a hexadecimal String.
    895     * @throws IOException If an I/O error occurs.
    896     * @since 1.11
    897     */
    898    public String hmacHex(final File valueToDigest) throws IOException {
    899        return Hex.encodeHexString(hmac(valueToDigest));
    900    }
    901
    902    /**
    903     * Returns the digest for the stream.
    904     *
    905     * @param valueToDigest The data to use.
    906     *                      <p>
    907     *                      The InputStream must not be null and will not be closed.
    908     *                      </p>
    909     * @return The digest as a hexadecimal String.
    910     * @throws IOException If an I/O error occurs.
    911     * @since 1.11
    912     */
    913    public String hmacHex(final InputStream valueToDigest) throws IOException {
    914        return Hex.encodeHexString(hmac(valueToDigest));
    915    }
    916
    917    /**
    918     * Returns the digest for the path.
    919     *
    920     * @param valueToDigest The path to use.
    921     * @return The digest as a hexadecimal String.
    922     * @throws IOException If an I/O error occurs.
    923     * @since 1.19.0
    924     */
    925    public String hmacHex(final Path valueToDigest) throws IOException {
    926        return Hex.encodeHexString(hmac(valueToDigest));
    927    }
    928
    929    /**
    930     * Returns the digest for the input data.
    931     *
    932     * @param valueToDigest The input to use, treated as UTF-8.
    933     * @return The digest as a hexadecimal String.
    934     * @since 1.11
    935     */
    936    public String hmacHex(final String valueToDigest) {
    937        return Hex.encodeHexString(hmac(valueToDigest));
    938    }
    939}