HmacUtils.java

  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. package org.apache.commons.codec.digest;

  18. import java.io.BufferedInputStream;
  19. import java.io.File;
  20. import java.io.FileInputStream;
  21. import java.io.IOException;
  22. import java.io.InputStream;
  23. import java.nio.ByteBuffer;
  24. import java.security.InvalidKeyException;
  25. import java.security.Key;
  26. import java.security.NoSuchAlgorithmException;

  27. import javax.crypto.Mac;
  28. import javax.crypto.spec.SecretKeySpec;

  29. import org.apache.commons.codec.binary.Hex;
  30. import org.apache.commons.codec.binary.StringUtils;

  31. /**
  32.  * Simplifies common {@link javax.crypto.Mac} tasks. This class is immutable and thread-safe.
  33.  * However the Mac may not be.
  34.  * <p>
  35.  * <strong>Note: Not all JCE implementations support all algorithms. If not supported, an IllegalArgumentException is
  36.  * thrown.</strong>
  37.  * <p>
  38.  * Sample usage:
  39.  * <pre>
  40.  * import static HmacAlgorithms.*;
  41.  * byte[] key = {1,2,3,4}; // don't use this actual key!
  42.  * String valueToDigest = "The quick brown fox jumps over the lazy dog";
  43.  * byte[] hmac = new HmacUtils(HMAC_SHA_224, key).hmac(valueToDigest);
  44.  * // Mac re-use
  45.  * HmacUtils hm1 = new HmacUtils("HmacAlgoName", key); // use a valid name here!
  46.  * String hexPom = hm1.hmacHex(new File("pom.xml"));
  47.  * String hexNot = hm1.hmacHex(new File("NOTICE.txt"));
  48.  * </pre>
  49.  * @since 1.10
  50.  * @version $Id: HmacUtils.java 1811344 2017-10-06 15:19:57Z ggregory $
  51.  */
  52. public final class HmacUtils {

  53.     private static final int STREAM_BUFFER_LENGTH = 1024;

  54.     /**
  55.     * Returns whether this algorithm is available
  56.     *
  57.     *@param name the name to check
  58.     * @return whether this algorithm is available
  59.     * @since 1.11
  60.     */
  61.     public static boolean isAvailable(final String name) {
  62.         try {
  63.             Mac.getInstance(name);
  64.             return true;
  65.         } catch (final NoSuchAlgorithmException e) {
  66.             return false;
  67.         }
  68.     }

  69.     /**
  70.     * Returns whether this algorithm is available
  71.     *
  72.     *@param name the name to check
  73.     * @return whether this algorithm is available
  74.     * @since 1.11
  75.     */
  76.     public static boolean isAvailable(final HmacAlgorithms name) {
  77.         try {
  78.             Mac.getInstance(name.getName());
  79.             return true;
  80.         } catch (final NoSuchAlgorithmException e) {
  81.             return false;
  82.         }
  83.     }

  84.     /**
  85.      * Returns an initialized <code>Mac</code> for the HmacMD5 algorithm.
  86.      * <p>
  87.      * Every implementation of the Java platform is required to support this standard Mac algorithm.
  88.      * </p>
  89.      *
  90.      * @param key
  91.      *            They key for the keyed digest (must not be null)
  92.      * @return A Mac instance initialized with the given key.
  93.      * @see Mac#getInstance(String)
  94.      * @see Mac#init(Key)
  95.      * @throws IllegalArgumentException
  96.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  97.      * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_MD5, byte[])}
  98.      */
  99.     @Deprecated
  100.     public static Mac getHmacMd5(final byte[] key) {
  101.         return getInitializedMac(HmacAlgorithms.HMAC_MD5, key);
  102.     }

  103.     /**
  104.      * Returns an initialized <code>Mac</code> for the HmacSHA1 algorithm.
  105.      * <p>
  106.      * Every implementation of the Java platform is required to support this standard Mac algorithm.
  107.      * </p>
  108.      *
  109.      * @param key
  110.      *            They key for the keyed digest (must not be null)
  111.      * @return A Mac instance initialized with the given key.
  112.      * @see Mac#getInstance(String)
  113.      * @see Mac#init(Key)
  114.      * @throws IllegalArgumentException
  115.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  116.      * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_1, byte[])}
  117.      */
  118.     @Deprecated
  119.     public static Mac getHmacSha1(final byte[] key) {
  120.         return getInitializedMac(HmacAlgorithms.HMAC_SHA_1, key);
  121.     }

  122.     /**
  123.      * Returns an initialized <code>Mac</code> for the HmacSHA256 algorithm.
  124.      * <p>
  125.      * Every implementation of the Java platform is required to support this standard Mac algorithm.
  126.      * </p>
  127.      *
  128.      * @param key
  129.      *            They 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_256, byte[])}
  136.      */
  137.     @Deprecated
  138.     public static Mac getHmacSha256(final byte[] key) {
  139.         return getInitializedMac(HmacAlgorithms.HMAC_SHA_256, key);
  140.     }

  141.     /**
  142.      * Returns an initialized <code>Mac</code> for the HmacSHA384 algorithm.
  143.      * <p>
  144.      * Every implementation of the Java platform is <em>not</em> required to support this Mac algorithm.
  145.      * </p>
  146.      *
  147.      * @param key
  148.      *            They key for the keyed digest (must not be null)
  149.      * @return A Mac instance initialized with the given key.
  150.      * @see Mac#getInstance(String)
  151.      * @see Mac#init(Key)
  152.      * @throws IllegalArgumentException
  153.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  154.      * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_384, byte[])}
  155.      */
  156.     @Deprecated
  157.     public static Mac getHmacSha384(final byte[] key) {
  158.         return getInitializedMac(HmacAlgorithms.HMAC_SHA_384, key);
  159.     }

  160.     /**
  161.      * Returns an initialized <code>Mac</code> for the HmacSHA512 algorithm.
  162.      * <p>
  163.      * Every implementation of the Java platform is <em>not</em> required to support this Mac algorithm.
  164.      * </p>
  165.      *
  166.      * @param key
  167.      *            They key for the keyed digest (must not be null)
  168.      * @return A Mac instance initialized with the given key.
  169.      * @see Mac#getInstance(String)
  170.      * @see Mac#init(Key)
  171.      * @throws IllegalArgumentException
  172.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  173.      * @deprecated (1.11) Use {@code getInitializedMac(HmacAlgorithms.HMAC_SHA_512, byte[])}
  174.      */
  175.     @Deprecated
  176.     public static Mac getHmacSha512(final byte[] key) {
  177.         return getInitializedMac(HmacAlgorithms.HMAC_SHA_512, key);
  178.     }

  179.     /**
  180.      * Returns an initialized <code>Mac</code> for the given <code>algorithm</code>.
  181.      *
  182.      * @param algorithm
  183.      *            the name of the algorithm requested. See
  184.      *            <a href= "http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA"
  185.      *            >Appendix A in the Java Cryptography Architecture Reference Guide</a> for information about standard
  186.      *            algorithm names.
  187.      * @param key
  188.      *            They key for the keyed digest (must not be null)
  189.      * @return A Mac instance initialized with the given key.
  190.      * @see Mac#getInstance(String)
  191.      * @see Mac#init(Key)
  192.      * @throws IllegalArgumentException
  193.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  194.      */
  195.     public static Mac getInitializedMac(final HmacAlgorithms algorithm, final byte[] key) {
  196.         return getInitializedMac(algorithm.getName(), key);
  197.     }

  198.     /**
  199.      * Returns an initialized <code>Mac</code> for the given <code>algorithm</code>.
  200.      *
  201.      * @param algorithm
  202.      *            the name of the algorithm requested. See
  203.      *            <a href= "http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA"
  204.      *            >Appendix A in the Java Cryptography Architecture Reference Guide</a> for information about standard
  205.      *            algorithm names.
  206.      * @param key
  207.      *            They key for the keyed digest (must not be null)
  208.      * @return A Mac instance initialized with the given key.
  209.      * @see Mac#getInstance(String)
  210.      * @see Mac#init(Key)
  211.      * @throws IllegalArgumentException
  212.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  213.      */
  214.     public static Mac getInitializedMac(final String algorithm, final byte[] key) {

  215.         if (key == null) {
  216.             throw new IllegalArgumentException("Null key");
  217.         }

  218.         try {
  219.             final SecretKeySpec keySpec = new SecretKeySpec(key, algorithm);
  220.             final Mac mac = Mac.getInstance(algorithm);
  221.             mac.init(keySpec);
  222.             return mac;
  223.         } catch (final NoSuchAlgorithmException e) {
  224.             throw new IllegalArgumentException(e);
  225.         } catch (final InvalidKeyException e) {
  226.             throw new IllegalArgumentException(e);
  227.         }
  228.     }

  229.     // hmacMd5

  230.     /**
  231.      * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value.
  232.      *
  233.      * @param key
  234.      *            They key for the keyed digest (must not be null)
  235.      * @param valueToDigest
  236.      *            The value (data) which should to digest (maybe empty or null)
  237.      * @return HmacMD5 MAC for the given key and value
  238.      * @throws IllegalArgumentException
  239.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  240.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmac(byte[])}
  241.      */
  242.     @Deprecated
  243.     public static byte[] hmacMd5(final byte[] key, final byte[] valueToDigest) {
  244.         return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmac(valueToDigest);
  245.     }

  246.     /**
  247.      * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value.
  248.      *
  249.      * @param key
  250.      *            They key for the keyed digest (must not be null)
  251.      * @param valueToDigest
  252.      *            The value (data) which should to digest
  253.      *            <p>
  254.      *            The InputStream must not be null and will not be closed
  255.      *            </p>
  256.      * @return HmacMD5 MAC for the given key and value
  257.      * @throws IOException
  258.      *             If an I/O error occurs.
  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, byte[]).hmac(InputStream)}
  262.      */
  263.     @Deprecated
  264.     public static byte[] hmacMd5(final byte[] key, final InputStream valueToDigest) throws IOException {
  265.         return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmac(valueToDigest);
  266.     }

  267.     /**
  268.      * Returns a HmacMD5 Message Authentication Code (MAC) for the given key and value.
  269.      *
  270.      * @param key
  271.      *            They key for the keyed digest (must not be null)
  272.      * @param valueToDigest
  273.      *            The value (data) which should to digest (maybe empty or null)
  274.      * @return HmacMD5 MAC for the given key and value
  275.      * @throws IllegalArgumentException
  276.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  277.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, String).hmac(String)}
  278.      */
  279.     @Deprecated
  280.     public static byte[] hmacMd5(final String key, final String valueToDigest) {
  281.         return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmac(valueToDigest);
  282.     }

  283.     /**
  284.      * Returns a HmacMD5 Message Authentication Code (MAC) as a hex string (lowercase) for the given key and value.
  285.      *
  286.      * @param key
  287.      *            They key for the keyed digest (must not be null)
  288.      * @param valueToDigest
  289.      *            The value (data) which should to digest (maybe empty or null)
  290.      * @return HmacMD5 MAC for the given key and value as a hex string (lowercase)
  291.      * @throws IllegalArgumentException
  292.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  293.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmacHex(byte[])}
  294.      */
  295.     @Deprecated
  296.     public static String hmacMd5Hex(final byte[] key, final byte[] valueToDigest) {
  297.         return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(valueToDigest);
  298.     }

  299.     /**
  300.      * Returns a HmacMD5 Message Authentication Code (MAC) as a hex string (lowercase) for the given key and value.
  301.      *
  302.      * @param key
  303.      *            They key for the keyed digest (must not be null)
  304.      * @param valueToDigest
  305.      *            The value (data) which should to digest
  306.      *            <p>
  307.      *            The InputStream must not be null and will not be closed
  308.      *            </p>
  309.      * @return HmacMD5 MAC for the given key and value as a hex string (lowercase)
  310.      * @throws IOException
  311.      *             If an I/O error occurs.
  312.      * @throws IllegalArgumentException
  313.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  314.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, byte[]).hmacHex(InputStream)}
  315.      */
  316.     @Deprecated
  317.     public static String hmacMd5Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
  318.         return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(valueToDigest);
  319.     }

  320.     /**
  321.      * Returns a HmacMD5 Message Authentication Code (MAC) as a hex string (lowercase) for the given key and value.
  322.      *
  323.      * @param key
  324.      *            They key for the keyed digest (must not be null)
  325.      * @param valueToDigest
  326.      *            The value (data) which should to digest (maybe empty or null)
  327.      * @return HmacMD5 MAC for the given key and value as a hex string (lowercase)
  328.      * @throws IllegalArgumentException
  329.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  330.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_MD5, String).hmacHex(String)}
  331.      */
  332.     @Deprecated
  333.     public static String hmacMd5Hex(final String key, final String valueToDigest) {
  334.         return new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(valueToDigest);
  335.     }

  336.     // hmacSha1

  337.     /**
  338.      * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value.
  339.      *
  340.      * @param key
  341.      *            They key for the keyed digest (must not be null)
  342.      * @param valueToDigest
  343.      *            The value (data) which should to digest (maybe empty or null)
  344.      * @return HmacSHA1 MAC for the given key and value
  345.      * @throws IllegalArgumentException
  346.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  347.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmac(byte[])}
  348.      */
  349.     @Deprecated
  350.     public static byte[] hmacSha1(final byte[] key, final byte[] valueToDigest) {
  351.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmac(valueToDigest);
  352.     }

  353.     /**
  354.      * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value.
  355.      *
  356.      * @param key
  357.      *            They key for the keyed digest (must not be null)
  358.      * @param valueToDigest
  359.      *            The value (data) which should to digest
  360.      *            <p>
  361.      *            The InputStream must not be null and will not be closed
  362.      *            </p>
  363.      * @return HmacSHA1 MAC for the given key and value
  364.      * @throws IOException
  365.      *             If an I/O error occurs.
  366.      * @throws IllegalArgumentException
  367.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  368.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmac(InputStream)}
  369.      */
  370.     @Deprecated
  371.     public static byte[] hmacSha1(final byte[] key, final InputStream valueToDigest) throws IOException {
  372.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmac(valueToDigest);
  373.     }

  374.     /**
  375.      * Returns a HmacSHA1 Message Authentication Code (MAC) for the given key and value.
  376.      *
  377.      * @param key
  378.      *            They key for the keyed digest (must not be null)
  379.      * @param valueToDigest
  380.      *            The value (data) which should to digest (maybe empty or null)
  381.      * @return HmacSHA1 MAC for the given key and value
  382.      * @throws IllegalArgumentException
  383.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  384.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, String).hmac(String)}
  385.      */
  386.     @Deprecated
  387.     public static byte[] hmacSha1(final String key, final String valueToDigest) {
  388.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmac(valueToDigest);
  389.     }

  390.     /**
  391.      * Returns a HmacSHA1 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value.
  392.      *
  393.      * @param key
  394.      *            They key for the keyed digest (must not be null)
  395.      * @param valueToDigest
  396.      *            The value (data) which should to digest (maybe empty or null)
  397.      * @return HmacSHA1 MAC for the given key and value as hex string (lowercase)
  398.      * @throws IllegalArgumentException
  399.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  400.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmacHex(byte[])}
  401.      */
  402.     @Deprecated
  403.     public static String hmacSha1Hex(final byte[] key, final byte[] valueToDigest) {
  404.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(valueToDigest);
  405.     }

  406.     /**
  407.      * Returns a HmacSHA1 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value.
  408.      *
  409.      * @param key
  410.      *            They key for the keyed digest (must not be null)
  411.      * @param valueToDigest
  412.      *            The value (data) which should to digest
  413.      *            <p>
  414.      *            The InputStream must not be null and will not be closed
  415.      *            </p>
  416.      * @return HmacSHA1 MAC for the given key and value as hex string (lowercase)
  417.      * @throws IOException
  418.      *             If an I/O error occurs.
  419.      * @throws IllegalArgumentException
  420.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  421.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, byte[]).hmacHex(InputStream)}
  422.      */
  423.     @Deprecated
  424.     public static String hmacSha1Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
  425.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(valueToDigest);
  426.     }

  427.     /**
  428.      * Returns a HmacSHA1 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value.
  429.      *
  430.      * @param key
  431.      *            They key for the keyed digest (must not be null)
  432.      * @param valueToDigest
  433.      *            The value (data) which should to digest (maybe empty or null)
  434.      * @return HmacSHA1 MAC for the given key and value as hex string (lowercase)
  435.      * @throws IllegalArgumentException
  436.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  437.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_1, String).hmacHex(String)}
  438.      */
  439.     @Deprecated
  440.     public static String hmacSha1Hex(final String key, final String valueToDigest) {
  441.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, key).hmacHex(valueToDigest);
  442.     }

  443.     // hmacSha256

  444.     /**
  445.      * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value.
  446.      *
  447.      * @param key
  448.      *            They key for the keyed digest (must not be null)
  449.      * @param valueToDigest
  450.      *            The value (data) which should to digest (maybe empty or null)
  451.      * @return HmacSHA256 MAC for the given key and value
  452.      * @throws IllegalArgumentException
  453.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  454.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmac(byte[])}
  455.      */
  456.     @Deprecated
  457.     public static byte[] hmacSha256(final byte[] key, final byte[] valueToDigest) {
  458.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(valueToDigest);
  459.     }

  460.     /**
  461.      * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value.
  462.      *
  463.      * @param key
  464.      *            They key for the keyed digest (must not be null)
  465.      * @param valueToDigest
  466.      *            The value (data) which should to digest
  467.      *            <p>
  468.      *            The InputStream must not be null and will not be closed
  469.      *            </p>
  470.      * @return HmacSHA256 MAC for the given key and value
  471.      * @throws IOException
  472.      *             If an I/O error occurs.
  473.      * @throws IllegalArgumentException
  474.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  475.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmac(InputStream)}
  476.      */
  477.     @Deprecated
  478.     public static byte[] hmacSha256(final byte[] key, final InputStream valueToDigest) throws IOException {
  479.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(valueToDigest);
  480.     }

  481.     /**
  482.      * Returns a HmacSHA256 Message Authentication Code (MAC) for the given key and value.
  483.      *
  484.      * @param key
  485.      *            They key for the keyed digest (must not be null)
  486.      * @param valueToDigest
  487.      *            The value (data) which should to digest (maybe empty or null)
  488.      * @return HmacSHA256 MAC for the given key and value
  489.      * @throws IllegalArgumentException
  490.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  491.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, String).hmac(String)}
  492.      */
  493.     @Deprecated
  494.     public static byte[] hmacSha256(final String key, final String valueToDigest) {
  495.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(valueToDigest);
  496.     }

  497.     /**
  498.      * Returns a HmacSHA256 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value.
  499.      *
  500.      * @param key
  501.      *            They key for the keyed digest (must not be null)
  502.      * @param valueToDigest
  503.      *            The value (data) which should to digest (maybe empty or null)
  504.      * @return HmacSHA256 MAC for the given key and value as hex string (lowercase)
  505.      * @throws IllegalArgumentException
  506.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  507.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmacHex(byte[])}
  508.      */
  509.     @Deprecated
  510.     public static String hmacSha256Hex(final byte[] key, final byte[] valueToDigest) {
  511.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest);
  512.     }

  513.     /**
  514.      * Returns a HmacSHA256 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value.
  515.      *
  516.      * @param key
  517.      *            They key for the keyed digest (must not be null)
  518.      * @param valueToDigest
  519.      *            The value (data) which should to digest
  520.      *            <p>
  521.      *            The InputStream must not be null and will not be closed
  522.      *            </p>
  523.      * @return HmacSHA256 MAC for the given key and value as hex string (lowercase)
  524.      * @throws IOException
  525.      *             If an I/O error occurs.
  526.      * @throws IllegalArgumentException
  527.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  528.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, byte[]).hmacHex(InputStream)}
  529.      */
  530.     @Deprecated
  531.     public static String hmacSha256Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
  532.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest);
  533.     }

  534.     /**
  535.      * Returns a HmacSHA256 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value.
  536.      *
  537.      * @param key
  538.      *            They key for the keyed digest (must not be null)
  539.      * @param valueToDigest
  540.      *            The value (data) which should to digest (maybe empty or null)
  541.      * @return HmacSHA256 MAC for the given key and value as hex string (lowercase)
  542.      * @throws IllegalArgumentException
  543.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  544.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_256, String).hmacHex(String)}
  545.      */
  546.     @Deprecated
  547.     public static String hmacSha256Hex(final String key, final String valueToDigest) {
  548.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(valueToDigest);
  549.     }

  550.     // hmacSha384

  551.     /**
  552.      * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value.
  553.      *
  554.      * @param key
  555.      *            They key for the keyed digest (must not be null)
  556.      * @param valueToDigest
  557.      *            The value (data) which should to digest (maybe empty or null)
  558.      * @return HmacSHA384 MAC for the given key and value
  559.      * @throws IllegalArgumentException
  560.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  561.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmac(byte[])}
  562.      */
  563.     @Deprecated
  564.     public static byte[] hmacSha384(final byte[] key, final byte[] valueToDigest) {
  565.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest);
  566.     }

  567.     /**
  568.      * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value.
  569.      *
  570.      * @param key
  571.      *            They 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.      * Returns a HmacSHA384 Message Authentication Code (MAC) for the given key and value.
  590.      *
  591.      * @param key
  592.      *            They key for the keyed digest (must not be null)
  593.      * @param valueToDigest
  594.      *            The value (data) which should to digest (maybe empty or null)
  595.      * @return HmacSHA384 MAC for the given key and value
  596.      * @throws IllegalArgumentException
  597.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  598.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, String).hmac(String)}
  599.      */
  600.     @Deprecated
  601.     public static byte[] hmacSha384(final String key, final String valueToDigest) {
  602.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmac(valueToDigest);
  603.     }

  604.     /**
  605.      * Returns a HmacSHA384 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value.
  606.      *
  607.      * @param key
  608.      *            They key for the keyed digest (must not be null)
  609.      * @param valueToDigest
  610.      *            The value (data) which should to digest (maybe empty or null)
  611.      * @return HmacSHA384 MAC for the given key and value as hex string (lowercase)
  612.      * @throws IllegalArgumentException
  613.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  614.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmacHex(byte[])}
  615.      */
  616.     @Deprecated
  617.     public static String hmacSha384Hex(final byte[] key, final byte[] valueToDigest) {
  618.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest);
  619.     }

  620.     /**
  621.      * Returns a HmacSHA384 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value.
  622.      *
  623.      * @param key
  624.      *            They key for the keyed digest (must not be null)
  625.      * @param valueToDigest
  626.      *            The value (data) which should to digest
  627.      *            <p>
  628.      *            The InputStream must not be null and will not be closed
  629.      *            </p>
  630.      * @return HmacSHA384 MAC for the given key and value as hex string (lowercase)
  631.      * @throws IOException
  632.      *             If an I/O error occurs.
  633.      * @throws IllegalArgumentException
  634.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  635.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, byte[]).hmacHex(InputStream)}
  636.      */
  637.     @Deprecated
  638.     public static String hmacSha384Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
  639.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest);
  640.     }

  641.     /**
  642.      * Returns a HmacSHA384 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value.
  643.      *
  644.      * @param key
  645.      *            They key for the keyed digest (must not be null)
  646.      * @param valueToDigest
  647.      *            The value (data) which should to digest (maybe empty or null)
  648.      * @return HmacSHA384 MAC for the given key and value as hex string (lowercase)
  649.      * @throws IllegalArgumentException
  650.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  651.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_384, String).hmacHex(String)}
  652.      */
  653.     @Deprecated
  654.     public static String hmacSha384Hex(final String key, final String valueToDigest) {
  655.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, key).hmacHex(valueToDigest);
  656.     }

  657.     // hmacSha512

  658.     /**
  659.      * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value.
  660.      *
  661.      * @param key
  662.      *            They key for the keyed digest (must not be null)
  663.      * @param valueToDigest
  664.      *            The value (data) which should to digest (maybe empty or null)
  665.      * @return HmacSHA512 MAC for the given key and value
  666.      * @throws IllegalArgumentException
  667.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  668.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmac(byte[])}
  669.      */
  670.     @Deprecated
  671.     public static byte[] hmacSha512(final byte[] key, final byte[] valueToDigest) {
  672.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest);
  673.     }

  674.     /**
  675.      * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value.
  676.      *
  677.      * @param key
  678.      *            They key for the keyed digest (must not be null)
  679.      * @param valueToDigest
  680.      *            The value (data) which should to digest
  681.      *            <p>
  682.      *            The InputStream must not be null and will not be closed
  683.      *            </p>
  684.      * @return HmacSHA512 MAC for the given key and value
  685.      * @throws IOException
  686.      *             If an I/O error occurs.
  687.      * @throws IllegalArgumentException
  688.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  689.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmac(InputStream)}
  690.      */
  691.     @Deprecated
  692.     public static byte[] hmacSha512(final byte[] key, final InputStream valueToDigest) throws IOException {
  693.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest);
  694.     }

  695.     /**
  696.      * Returns a HmacSHA512 Message Authentication Code (MAC) for the given key and value.
  697.      *
  698.      * @param key
  699.      *            They key for the keyed digest (must not be null)
  700.      * @param valueToDigest
  701.      *            The value (data) which should to digest (maybe empty or null)
  702.      * @return HmacSHA512 MAC for the given key and value
  703.      * @throws IllegalArgumentException
  704.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  705.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, String).hmac(String)}
  706.      */
  707.     @Deprecated
  708.     public static byte[] hmacSha512(final String key, final String valueToDigest) {
  709.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmac(valueToDigest);
  710.     }

  711.     /**
  712.      * Returns a HmacSHA512 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value.
  713.      *
  714.      * @param key
  715.      *            They key for the keyed digest (must not be null)
  716.      * @param valueToDigest
  717.      *            The value (data) which should to digest (maybe empty or null)
  718.      * @return HmacSHA512 MAC for the given key and value as hex string (lowercase)
  719.      * @throws IllegalArgumentException
  720.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  721.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmacHex(byte[])}
  722.      */
  723.     @Deprecated
  724.     public static String hmacSha512Hex(final byte[] key, final byte[] valueToDigest) {
  725.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest);
  726.     }

  727.     /**
  728.      * Returns a HmacSHA512 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value.
  729.      *
  730.      * @param key
  731.      *            They key for the keyed digest (must not be null)
  732.      * @param valueToDigest
  733.      *            The value (data) which should to digest
  734.      *            <p>
  735.      *            The InputStream must not be null and will not be closed
  736.      *            </p>
  737.      * @return HmacSHA512 MAC for the given key and value as hex string (lowercase)
  738.      * @throws IOException
  739.      *             If an I/O error occurs.
  740.      * @throws IllegalArgumentException
  741.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  742.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, byte[]).hmacHex(InputStream)}
  743.      */
  744.     @Deprecated
  745.     public static String hmacSha512Hex(final byte[] key, final InputStream valueToDigest) throws IOException {
  746.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest);
  747.     }

  748.     /**
  749.      * Returns a HmacSHA512 Message Authentication Code (MAC) as hex string (lowercase) for the given key and value.
  750.      *
  751.      * @param key
  752.      *            They key for the keyed digest (must not be null)
  753.      * @param valueToDigest
  754.      *            The value (data) which should to digest (maybe empty or null)
  755.      * @return HmacSHA512 MAC for the given key and value as hex string (lowercase)
  756.      * @throws IllegalArgumentException
  757.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  758.      * @deprecated (1.11) Use {@code new HmacUtils(HmacAlgorithms.HMAC_SHA_512, String).hmacHex(String)}
  759.      */
  760.     @Deprecated
  761.     public static String hmacSha512Hex(final String key, final String valueToDigest) {
  762.         return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(valueToDigest);
  763.     }

  764.     // update

  765.     /**
  766.      * Resets and then updates the given {@link Mac} with the value.
  767.      *
  768.      * @param mac
  769.      *            the initialized {@link Mac} to update
  770.      * @param valueToDigest
  771.      *            the value to update the {@link Mac} with (maybe null or empty)
  772.      * @return the updated {@link Mac}
  773.      * @throws IllegalStateException
  774.      *             if the Mac was not initialized
  775.      */
  776.     public static Mac updateHmac(final Mac mac, final byte[] valueToDigest) {
  777.         mac.reset();
  778.         mac.update(valueToDigest);
  779.         return mac;
  780.     }

  781.     /**
  782.      * Resets and then updates the given {@link Mac} with the value.
  783.      *
  784.      * @param mac
  785.      *            the initialized {@link Mac} to update
  786.      * @param valueToDigest
  787.      *            the value to update the {@link Mac} with
  788.      *            <p>
  789.      *            The InputStream must not be null and will not be closed
  790.      *            </p>
  791.      * @return the updated {@link Mac}
  792.      * @throws IOException
  793.      *             If an I/O error occurs.
  794.      * @throws IllegalStateException
  795.      *             If the Mac was not initialized
  796.      */
  797.     public static Mac updateHmac(final Mac mac, final InputStream valueToDigest) throws IOException {
  798.         mac.reset();
  799.         final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
  800.         int read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH);

  801.         while (read > -1) {
  802.             mac.update(buffer, 0, read);
  803.             read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH);
  804.         }

  805.         return mac;
  806.     }

  807.     /**
  808.      * Resets and then updates the given {@link Mac} with the value.
  809.      *
  810.      * @param mac
  811.      *            the initialized {@link Mac} to update
  812.      * @param valueToDigest
  813.      *            the value to update the {@link Mac} with (maybe null or empty)
  814.      * @return the updated {@link Mac}
  815.      * @throws IllegalStateException
  816.      *             if the Mac was not initialized
  817.      */
  818.     public static Mac updateHmac(final Mac mac, final String valueToDigest) {
  819.         mac.reset();
  820.         mac.update(StringUtils.getBytesUtf8(valueToDigest));
  821.         return mac;
  822.     }

  823.     /**
  824.      * Preserves binary compatibity only.
  825.      * As for previous versions does not provide useful behaviour
  826.      * @deprecated since 1.11; only useful to preserve binary compatibility
  827.      */
  828.     @Deprecated
  829.     public HmacUtils() {
  830.         this(null);
  831.     }

  832.     private final Mac mac;

  833.     private HmacUtils(final Mac mac) {
  834.         this.mac = mac;
  835.     }

  836.     /**
  837.      * Creates an instance using the provided algorithm type.
  838.      *
  839.      * @param algorithm to use
  840.      * @param  key the key to use
  841.      * @throws IllegalArgumentException
  842.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  843.      * @since 1.11
  844.      */
  845.     public HmacUtils(final String algorithm, final byte[] key) {
  846.         this(getInitializedMac(algorithm, key));
  847.     }

  848.     /**
  849.      * Creates an instance using the provided algorithm type.
  850.      *
  851.      * @param algorithm to use
  852.      * @param  key the key to use
  853.      * @throws IllegalArgumentException
  854.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  855.      * @since 1.11
  856.      */
  857.     public HmacUtils(final String algorithm, final String key) {
  858.         this(algorithm, StringUtils.getBytesUtf8(key));
  859.     }

  860.     /**
  861.      * Creates an instance using the provided algorithm type.
  862.      *
  863.      * @param algorithm to use
  864.      * @param  key the key to use
  865.      * @throws IllegalArgumentException
  866.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  867.      * @since 1.11
  868.      */
  869.     public HmacUtils(final HmacAlgorithms algorithm, final String key) {
  870.         this(algorithm.getName(), StringUtils.getBytesUtf8(key));
  871.     }

  872.     /**
  873.      * Creates an instance using the provided algorithm type.
  874.      *
  875.      * @param algorithm to use.
  876.      * @param key the key to use
  877.      * @throws IllegalArgumentException
  878.      *             when a {@link NoSuchAlgorithmException} is caught or key is null or key is invalid.
  879.      * @since 1.11
  880.      */
  881.     public HmacUtils(final HmacAlgorithms algorithm, final byte[] key) {
  882.         this(algorithm.getName(), key);
  883.     }

  884.     /**
  885.      * Returns the digest for the input data.
  886.      *
  887.      * @param valueToDigest the input to use
  888.      * @return the digest as a byte[]
  889.      * @since 1.11
  890.      */
  891.     public byte[] hmac(final byte[] valueToDigest) {
  892.         return mac.doFinal(valueToDigest);
  893.     }

  894.     /**
  895.      * Returns the digest for the input data.
  896.      *
  897.      * @param valueToDigest the input to use
  898.      * @return the digest as a hex String
  899.      * @since 1.11
  900.      */
  901.     public String hmacHex(final byte[] valueToDigest) {
  902.         return Hex.encodeHexString(hmac(valueToDigest));
  903.     }

  904.     /**
  905.      * Returns the digest for the input data.
  906.      *
  907.      * @param valueToDigest the input to use, treated as UTF-8
  908.      * @return the digest as a byte[]
  909.      * @since 1.11
  910.      */
  911.     public byte[] hmac(final String valueToDigest) {
  912.         return mac.doFinal(StringUtils.getBytesUtf8(valueToDigest));
  913.     }

  914.     /**
  915.      * Returns the digest for the input data.
  916.      *
  917.      * @param valueToDigest the input to use, treated as UTF-8
  918.      * @return the digest as a hex String
  919.      * @since 1.11
  920.      */
  921.     public String hmacHex(final String valueToDigest) {
  922.         return Hex.encodeHexString(hmac(valueToDigest));
  923.     }

  924.     /**
  925.      * Returns the digest for the input data.
  926.      *
  927.      * @param valueToDigest the input to use
  928.      * @return the digest as a byte[]
  929.      * @since 1.11
  930.      */
  931.     public byte[] hmac(final ByteBuffer valueToDigest) {
  932.         mac.update(valueToDigest);
  933.         return mac.doFinal();
  934.     }

  935.     /**
  936.      * Returns the digest for the input data.
  937.      *
  938.      * @param valueToDigest the input to use
  939.      * @return the digest as a hex String
  940.      * @since 1.11
  941.      */
  942.     public String hmacHex(final ByteBuffer valueToDigest) {
  943.         return Hex.encodeHexString(hmac(valueToDigest));
  944.     }

  945.     /**
  946.      * Returns the digest for the stream.
  947.      *
  948.      * @param valueToDigest
  949.      *            the data to use
  950.      *            <p>
  951.      *            The InputStream must not be null and will not be closed
  952.      *            </p>
  953.      * @return the digest
  954.      * @throws IOException
  955.      *             If an I/O error occurs.
  956.      * @since 1.11
  957.      */
  958.     public byte[] hmac(final InputStream valueToDigest) throws IOException {
  959.         final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
  960.         int read;

  961.         while ((read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH) ) > -1) {
  962.             mac.update(buffer, 0, read);
  963.         }
  964.         return mac.doFinal();
  965.     }

  966.     /**
  967.      * Returns the digest for the stream.
  968.      *
  969.      * @param valueToDigest
  970.      *            the data to use
  971.      *            <p>
  972.      *            The InputStream must not be null and will not be closed
  973.      *            </p>
  974.      * @return the digest as a hex String
  975.      * @throws IOException
  976.      *             If an I/O error occurs.
  977.      * @since 1.11
  978.      */
  979.     public String hmacHex(final InputStream valueToDigest) throws IOException {
  980.         return Hex.encodeHexString(hmac(valueToDigest));
  981.     }

  982.     /**
  983.      * Returns the digest for the file.
  984.      *
  985.      * @param valueToDigest the file to use
  986.      * @return the digest
  987.      * @throws IOException
  988.      *             If an I/O error occurs.
  989.      * @since 1.11
  990.      */
  991.     public byte[] hmac(final File valueToDigest) throws IOException {
  992.         final BufferedInputStream stream = new BufferedInputStream(new FileInputStream(valueToDigest));
  993.         try {
  994.             return hmac(stream);
  995.         } finally {
  996.             stream.close();
  997.         }
  998.     }

  999.     /**
  1000.      * Returns the digest for the file.
  1001.      *
  1002.      * @param valueToDigest the file to use
  1003.      * @return the digest as a hex String
  1004.      * @throws IOException
  1005.      *             If an I/O error occurs.
  1006.      * @since 1.11
  1007.      */
  1008.     public String hmacHex(final File valueToDigest) throws IOException {
  1009.         return Hex.encodeHexString(hmac(valueToDigest));
  1010.     }

  1011. }