alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (MacHashFunctionTest.java)

This example Java source code file (MacHashFunctionTest.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

block-size, crypto, exception, hashfunction, hmacmd5, hmacsha1, larger, md5_key, override, secretkey, security, string, test, than, the, utf_8, util

The MacHashFunctionTest.java Java example source code

/*
 * Copyright (C) 2015 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.common.hash;

import static com.google.common.base.Charsets.UTF_8;
import static com.google.common.io.BaseEncoding.base16;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;
import com.google.common.testing.NullPointerTester;

import junit.framework.TestCase;

import sun.security.jca.ProviderList;
import sun.security.jca.Providers;

import java.security.Key;
import java.util.Arrays;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * Tests for the MacHashFunction.
 *
 * @author Kurt Alfred Kluever
 */
public class MacHashFunctionTest extends TestCase {

  private static final ImmutableSet<String> INPUTS = ImmutableSet.of("", "Z", "foobar");

  private static final SecretKey MD5_KEY =
      new SecretKeySpec("secret key".getBytes(UTF_8), "HmacMD5");
  private static final SecretKey SHA1_KEY =
      new SecretKeySpec("secret key".getBytes(UTF_8), "HmacSHA1");
  private static final SecretKey SHA256_KEY =
      new SecretKeySpec("secret key".getBytes(UTF_8), "HmacSHA256");
  private static final SecretKey SHA512_KEY =
      new SecretKeySpec("secret key".getBytes(UTF_8), "HmacSHA512");

  // From http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#Mac
  private static final ImmutableTable<String, SecretKey, HashFunction> ALGORITHMS =
      new ImmutableTable.Builder<String, SecretKey, HashFunction>()
          .put("HmacMD5", MD5_KEY, Hashing.hmacMd5(MD5_KEY))
          .put("HmacSHA1", SHA1_KEY, Hashing.hmacSha1(SHA1_KEY))
          .put("HmacSHA256", SHA256_KEY, Hashing.hmacSha256(SHA256_KEY))
          .put("HmacSHA512", SHA512_KEY, Hashing.hmacSha512(SHA512_KEY))
          .build();

  public void testNulls() {
    NullPointerTester tester = new NullPointerTester()
        .setDefault(String.class, "HmacMD5")
        .setDefault(Key.class, MD5_KEY);
    tester.testAllPublicConstructors(MacHashFunction.class);
    tester.testAllPublicInstanceMethods(new MacHashFunction("HmacMD5", MD5_KEY, "toString"));
  }

  public void testHashing() throws Exception {
    for (String stringToTest : INPUTS) {
      for (Table.Cell<String, SecretKey, HashFunction> cell : ALGORITHMS.cellSet()) {
        String algorithm = cell.getRowKey();
        SecretKey key = cell.getColumnKey();
        HashFunction hashFunc = cell.getValue();
        assertMacHashing(HashTestUtils.ascii(stringToTest), algorithm, key, hashFunc);
      }
    }
  }

  @AndroidIncompatible // sun.security
  public void testNoProviders() {
    ProviderList providers = Providers.getProviderList();
    Providers.setProviderList(ProviderList.newList());
    try {
      Hashing.hmacMd5(MD5_KEY);
      fail("expected ISE");
    } catch (IllegalStateException expected) {
    } finally {
      Providers.setProviderList(providers);
    }
  }

  public void testMultipleUpdates() throws Exception {
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(SHA1_KEY);
    mac.update("hello".getBytes(UTF_8));
    mac.update("world".getBytes(UTF_8));

    assertEquals(
        HashCode.fromBytes(mac.doFinal()),
        Hashing.hmacSha1(SHA1_KEY).newHasher()
            .putString("hello", UTF_8)
            .putString("world", UTF_8)
            .hash());
  }

  public void testMultipleUpdatesDoFinal() throws Exception {
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(SHA1_KEY);
    mac.update("hello".getBytes(UTF_8));
    mac.update("world".getBytes(UTF_8));

    assertEquals(
        HashCode.fromBytes(mac.doFinal("!!!".getBytes(UTF_8))),
        Hashing.hmacSha1(SHA1_KEY).newHasher()
            .putString("hello", UTF_8)
            .putString("world", UTF_8)
            .putString("!!!", UTF_8)
            .hash());
  }

  public void testCustomKey() throws Exception {
    SecretKey customKey = new SecretKey() {
      @Override public String getAlgorithm() {
        return "HmacMD5";
      }
      @Override public byte[] getEncoded() {
        return new byte[8];
      }
      @Override public String getFormat() {
        return "RAW";
      }
    };
    assertEquals("ad262969c53bc16032f160081c4a07a0",
        Hashing.hmacMd5(customKey)
            .hashString("The quick brown fox jumps over the lazy dog", UTF_8)
            .toString());
  }

  public void testBadKey_emptyKey() throws Exception {
    SecretKey badKey = new SecretKey() {
      @Override public String getAlgorithm() {
        return "HmacMD5";
      }
      @Override public byte[] getEncoded() {
        return null;
      }
      @Override public String getFormat() {
        return "RAW";
      }
    };
    try {
      Hashing.hmacMd5(badKey);
      fail();
    } catch (IllegalArgumentException expected) {
    } catch (NullPointerException toleratedOnAndroid) {
      // TODO(cpovirk): In an ideal world, we'd check here that we're running on Android.
    }
  }

  public void testEmptyInputs() throws Exception {
    String knownOutput = "8cbf764cbe2e4623d99a41354adfd390";

    Mac mac = Mac.getInstance("HmacMD5");
    mac.init(MD5_KEY);
    assertEquals(knownOutput, HashCode.fromBytes(mac.doFinal()).toString());
    assertEquals(knownOutput, Hashing.hmacMd5(MD5_KEY).newHasher().hash().toString());
  }

  public void testEmptyInputs_mixedAlgorithms() throws Exception {
    String knownOutput = "8cbf764cbe2e4623d99a41354adfd390";

    Mac mac = Mac.getInstance("HmacMD5");
    mac.init(SHA1_KEY);
    assertEquals(knownOutput, HashCode.fromBytes(mac.doFinal()).toString());
    assertEquals(knownOutput, Hashing.hmacMd5(SHA1_KEY).newHasher().hash().toString());
  }

  public void testKnownInputs() throws Exception {
    String knownOutput = "9753980fe94daa8ecaa82216519393a9";
    String input = "The quick brown fox jumps over the lazy dog";

    Mac mac = Mac.getInstance("HmacMD5");
    mac.init(MD5_KEY);
    mac.update(input.getBytes(UTF_8));
    assertEquals(knownOutput, HashCode.fromBytes(mac.doFinal()).toString());
    assertEquals(knownOutput, HashCode.fromBytes(mac.doFinal(input.getBytes(UTF_8))).toString());
    assertEquals(knownOutput, Hashing.hmacMd5(MD5_KEY).hashString(input, UTF_8).toString());
    assertEquals(knownOutput, Hashing.hmacMd5(MD5_KEY).hashBytes(input.getBytes(UTF_8)).toString());
  }

  public void testKnownInputs_mixedAlgorithms() throws Exception {
    String knownOutput = "9753980fe94daa8ecaa82216519393a9";
    String input = "The quick brown fox jumps over the lazy dog";

    Mac mac = Mac.getInstance("HmacMD5");
    mac.init(SHA1_KEY);
    mac.update(input.getBytes(UTF_8));
    assertEquals(knownOutput, HashCode.fromBytes(mac.doFinal()).toString());
    assertEquals(knownOutput, HashCode.fromBytes(mac.doFinal(input.getBytes(UTF_8))).toString());
    assertEquals(knownOutput, Hashing.hmacMd5(SHA1_KEY).hashString(input, UTF_8).toString());
    assertEquals(knownOutput,
        Hashing.hmacMd5(SHA1_KEY).hashBytes(input.getBytes(UTF_8)).toString());
  }

  public void testPutAfterHash() {
    Hasher hasher = Hashing.hmacMd5(MD5_KEY).newHasher();

    assertEquals("9753980fe94daa8ecaa82216519393a9",
        hasher.putString("The quick brown fox jumps over the lazy dog", UTF_8).hash().toString());
    try {
      hasher.putInt(42);
      fail();
    } catch (IllegalStateException expected) {
    }
  }

  public void testHashTwice() {
    Hasher hasher = Hashing.hmacMd5(MD5_KEY).newHasher();

    assertEquals("9753980fe94daa8ecaa82216519393a9",
        hasher.putString("The quick brown fox jumps over the lazy dog", UTF_8).hash().toString());
    try {
      hasher.hash();
      fail();
    } catch (IllegalStateException expected) {
    }
  }

  public void testToString() {
    byte[] keyData = "secret key".getBytes(UTF_8);

    assertEquals(
        "Hashing.hmacMd5(Key[algorithm=HmacMD5, format=RAW])",
        Hashing.hmacMd5(MD5_KEY).toString());
    assertEquals(
        "Hashing.hmacMd5(Key[algorithm=HmacMD5, format=RAW])",
        Hashing.hmacMd5(keyData).toString());

    assertEquals(
        "Hashing.hmacSha1(Key[algorithm=HmacSHA1, format=RAW])",
        Hashing.hmacSha1(SHA1_KEY).toString());
    assertEquals(
        "Hashing.hmacSha1(Key[algorithm=HmacSHA1, format=RAW])",
        Hashing.hmacSha1(keyData).toString());

    assertEquals(
        "Hashing.hmacSha256(Key[algorithm=HmacSHA256, format=RAW])",
        Hashing.hmacSha256(SHA256_KEY).toString());
    assertEquals(
        "Hashing.hmacSha256(Key[algorithm=HmacSHA256, format=RAW])",
        Hashing.hmacSha256(keyData).toString());

    assertEquals(
        "Hashing.hmacSha512(Key[algorithm=HmacSHA512, format=RAW])",
        Hashing.hmacSha512(SHA512_KEY).toString());
    assertEquals(
        "Hashing.hmacSha512(Key[algorithm=HmacSHA512, format=RAW])",
        Hashing.hmacSha512(keyData).toString());
  }

  private static void assertMacHashing(
      byte[] input, String algorithm, SecretKey key, HashFunction hashFunc) throws Exception {
    Mac mac = Mac.getInstance(algorithm);
    mac.init(key);
    mac.update(input);

    assertEquals(HashCode.fromBytes(mac.doFinal()), hashFunc.hashBytes(input));
    assertEquals(HashCode.fromBytes(mac.doFinal(input)), hashFunc.hashBytes(input));
  }

  // Tests from RFC2022: https://tools.ietf.org/html/rfc2202

  public void testRfc2202_hmacSha1_case1() {
    byte[] key = fillByteArray(20, 0x0b);
    String data = "Hi There";

    checkSha1("b617318655057264e28bc0b6fb378c8ef146be00", key, data);
  }

  public void testRfc2202_hmacSha1_case2() {
    byte[] key = "Jefe".getBytes(UTF_8);
    String data = "what do ya want for nothing?";

    checkSha1("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79", key, data);
  }

  public void testRfc2202_hmacSha1_case3() {
    byte[] key = fillByteArray(20, 0xaa);
    byte[] data = fillByteArray(50, 0xdd);

    checkSha1("125d7342b9ac11cd91a39af48aa17b4f63f175d3", key, data);
  }

  public void testRfc2202_hmacSha1_case4() {
    byte[] key = base16().lowerCase().decode("0102030405060708090a0b0c0d0e0f10111213141516171819");
    byte[] data = fillByteArray(50, 0xcd);

    checkSha1("4c9007f4026250c6bc8414f9bf50c86c2d7235da", key, data);
  }

  public void testRfc2202_hmacSha1_case5() {
    byte[] key = fillByteArray(20, 0x0c);
    String data = "Test With Truncation";

    checkSha1("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04", key, data);
  }

  public void testRfc2202_hmacSha1_case6() {
    byte[] key = fillByteArray(80, 0xaa);
    String data = "Test Using Larger Than Block-Size Key - Hash Key First";

    checkSha1("aa4ae5e15272d00e95705637ce8a3b55ed402112", key, data);
  }

  public void testRfc2202_hmacSha1_case7() {
    byte[] key = fillByteArray(80, 0xaa);
    String data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data";

    checkSha1("e8e99d0f45237d786d6bbaa7965c7808bbff1a91", key, data);
  }

  public void testRfc2202_hmacMd5_case1() {
    byte[] key = fillByteArray(16, 0x0b);
    String data = "Hi There";

    checkMd5("9294727a3638bb1c13f48ef8158bfc9d", key, data);
  }

  public void testRfc2202_hmacMd5_case2() {
    byte[] key = "Jefe".getBytes(UTF_8);
    String data = "what do ya want for nothing?";

    checkMd5("750c783e6ab0b503eaa86e310a5db738", key, data);
  }

  public void testRfc2202_hmacMd5_case3() {
    byte[] key = fillByteArray(16, 0xaa);
    byte[] data = fillByteArray(50, 0xdd);

    checkMd5("56be34521d144c88dbb8c733f0e8b3f6", key, data);
  }

  public void testRfc2202_hmacMd5_case4() {
    byte[] key = base16().lowerCase().decode("0102030405060708090a0b0c0d0e0f10111213141516171819");
    byte[] data = fillByteArray(50, 0xcd);

    checkMd5("697eaf0aca3a3aea3a75164746ffaa79", key, data);
  }

  public void testRfc2202_hmacMd5_case5() {
    byte[] key = fillByteArray(16, 0x0c);
    String data = "Test With Truncation";

    checkMd5("56461ef2342edc00f9bab995690efd4c", key, data);
  }

  public void testRfc2202_hmacMd5_case6() {
    byte[] key = fillByteArray(80, 0xaa);
    String data = "Test Using Larger Than Block-Size Key - Hash Key First";

    checkMd5("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd", key, data);
  }

  public void testRfc2202_hmacMd5_case7() {
    byte[] key = fillByteArray(80, 0xaa);
    String data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data";

    checkMd5("6f630fad67cda0ee1fb1f562db3aa53e", key, data);
  }

  private static void checkSha1(String expected, byte[] key, String data) {
    checkSha1(expected, key, data.getBytes(UTF_8));
  }

  private static void checkSha1(String expected, byte[] key, byte[] data) {
    checkHmac(expected, Hashing.hmacSha1(key), data);
  }

  private static void checkMd5(String expected, byte[] key, String data) {
    checkMd5(expected, key, data.getBytes(UTF_8));
  }

  private static void checkMd5(String expected, byte[] key, byte[] data) {
    checkHmac(expected, Hashing.hmacMd5(key), data);
  }

  private static void checkHmac(String expected, HashFunction hashFunc, byte[] data) {
    assertEquals(HashCode.fromString(expected), hashFunc.hashBytes(data));
  }

  private static byte[] fillByteArray(int size, int toFillWith) {
    byte[] array = new byte[size];
    Arrays.fill(array, (byte) toFillWith);
    return array;
  }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java MacHashFunctionTest.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.