Package com.google.k2crypto.keyversions

Source Code of com.google.k2crypto.keyversions.HMACKeyVersion$Builder

/*
* Copyright 2014 Google Inc. All rights reserved.
*
* 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.k2crypto.keyversions;

import com.google.k2crypto.exceptions.BuilderException;
import com.google.k2crypto.exceptions.EncryptionException;
import com.google.k2crypto.keyversions.HmacKeyVersionProto.Algorithm;
import com.google.k2crypto.keyversions.HmacKeyVersionProto.HmacKeyVersionCore;
import com.google.k2crypto.keyversions.HmacKeyVersionProto.HmacKeyVersionData;
import com.google.k2crypto.keyversions.KeyVersionProto.KeyVersionCore;
import com.google.k2crypto.keyversions.KeyVersionProto.KeyVersionData;
import com.google.protobuf.ByteString;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.InvalidProtocolBufferException;

import java.util.Arrays;

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

/**
* This class represents a hash key version in K2. It is abstract and extended
* by specific hash key implementations such as HMACKeyVersion
*
* @author John Maheswaran (maheswaran@google.com)
*/
@KeyVersionInfo(
    type = KeyVersionProto.Type.HMAC,
    proto = HmacKeyVersionProto.class)
public class HMACKeyVersion extends HashKeyVersion {
  /**
   * SecretKey object representing the key matter in the HMAC key version
   */
  private SecretKey secretKey;

  /**
   * Private constructor to ensure people use generateSHA1HMAC or
   * generateMD5HMAC to generate HMAC key
   */
  private HMACKeyVersion(Builder builder) throws Exception {
    super(builder);
    if (builder.keyVersionMatter == null) {
      // Generate a key for the HMAC-SHA1 keyed-hashing algorithm
      KeyGenerator keyGen = KeyGenerator.getInstance(builder.algorithm);
      secretKey = keyGen.generateKey();
    } else {
      // set the secret key based on the raw key matter
      secretKey = new SecretKeySpec(builder.keyVersionMatter,
          0, builder.keyVersionMatter.length, builder.algorithm);
    }
  }

  /**
   * String constants representing all supported hash algorithms.
   */
  public static final String HMAC_MD5 = "HmacMD5";
  public static final String HMAC_SHA1 = "HmacSHA1";
  public static final String HMAC_SHA256 = "HmacSHA256";
  public static final String HMAC_SHA384 = "HmacSHA384";
  public static final String HMAC_SHA512 = "HmacSHA512";

  /**
   * Hash algorithm for this HMAC key version
   */
  private String algorithm = HMAC_SHA1;

  /**
   * Generates a new HMAC using the SHA1 hash algorithm
   *
   * @return a new HMACKeyVersion using the SHA1 hash algorithm
   * @throws BuilderException
   */
  public static HMACKeyVersion generateHMAC(String hashAlgorithm)
      throws BuilderException {
    return new Builder().algorithm(hashAlgorithm).build();
  }

  /**
   * Generates a new HMAC using the SHA1 hash algorithm from give keyversion
   * matter
   *
   * @param keyVersionMatter The byte array representation of the
   *                         HMAC key version
   * @return an HMACKeyVersion object representing the HMAC key based on the
   *         input key version matter
   * @throws BuilderException
   */
  public static HMACKeyVersion generateHMAC(
      String hashAlgorithm, byte[] keyVersionMatter)
          throws BuilderException {
    return new Builder()
        .algorithm(hashAlgorithm).matterVector(keyVersionMatter).build();
  }

  /**
   * Public method to get the byte array of the HMAC key version matter
   *
   * @return The byte array representation of the HMAC key version matter
   */
  public byte[] getKeyVersionMatter() {
    return this.secretKey.getEncoded();
  }
 
  /**
   * Returns the digest algorithm for the HMAC.
   */
  public String getAlgorithm() {
    return algorithm;
  }

  /**
   * Method to compute the raw HMAC on a piece of input data
   *
   * @param inputData The data on which to compute the HMAC
   * @return The byte array representation of the HMAC
   * @throws EncryptionException
   */
  public byte[] getRawHMAC(byte[] inputData) throws EncryptionException {
    try {
      // get an HMAC Mac instance using the algorithm of this HMAC key
      Mac mac = Mac.getInstance(this.algorithm);
      // now initialize with the signing key it withthe key
      mac.init(this.secretKey);
      // compute the hmac on input data bytes
      byte[] hmacsig = mac.doFinal(inputData);
      // return the HMAC
      return hmacsig;
    } catch (Exception e) {
      // catch any exceptions and throw custom exception
      throw new EncryptionException("Failed to generate HMAC signature", e);
    }
  }

  /**
   * Method that verifies a given HMAC on a piece of data
   *
   * @param inputHmac The input HMAC to verify
   * @param message The input message to check the HMAC against
   * @return True if and only if the HMAC computed on the message matches the
   *         input HMAC, false otherwise
   * @throws EncryptionException
   */
  public boolean verifyHMAC(byte[] inputHmac, byte[] message)
      throws EncryptionException {
    // compute the hmac on the message
    // if the input hmac matches the computed hmac return true
    if (Arrays.equals(inputHmac, getRawHMAC(message))) {
      return true;
    }
    // otherwise return false as the computed hmac differs from the input hmac
    return false;
  }
 
  /**
   * @see KeyVersion#buildCore()
   */
  @Override
  protected KeyVersionCore.Builder buildCore() {
    HmacKeyVersionCore.Builder coreBuilder = HmacKeyVersionCore.newBuilder();
   
    // Populate the core builder
    coreBuilder.setMatter(ByteString.copyFrom(secretKey.getEncoded()));

    // TODO: change this to an enum...
    if (algorithm.equalsIgnoreCase(HMAC_MD5)) {
      coreBuilder.setAlgorithm(Algorithm.MD5)
    } else if (algorithm.equalsIgnoreCase(HMAC_SHA1)) {
      coreBuilder.setAlgorithm(Algorithm.SHA1)
    } else if (algorithm.equalsIgnoreCase(HMAC_SHA256)) {
      coreBuilder.setAlgorithm(Algorithm.SHA2_256)
    } else if (algorithm.equalsIgnoreCase(HMAC_SHA384)) {
      coreBuilder.setAlgorithm(Algorithm.SHA2_384)
    } else if (algorithm.equalsIgnoreCase(HMAC_SHA512)) {
      coreBuilder.setAlgorithm(Algorithm.SHA2_512)
    }
   
    KeyVersionCore.Builder builder = super.buildCore();
    builder.setExtension(HmacKeyVersionCore.extension, coreBuilder.build());
    return builder;
  }
 
  /**
   * @see KeyVersion#buildData()
   */
  @Override
  public KeyVersionData.Builder buildData() {
    HmacKeyVersionData.Builder dataBuilder = HmacKeyVersionData.newBuilder();
    // TODO(darylseah): Populate the data builder

    KeyVersionData.Builder builder = super.buildData();
    builder.setExtension(HmacKeyVersionData.extension, dataBuilder.build());
    return builder;
  }
 
  /**
   * This class represents a key version builder for HMAC key versions.
   *
   * @author John Maheswaran (maheswaran@google.com)
   */
  public static class Builder extends KeyVersion.Builder {
    /**
     * Hmac algorithm to use.
     */
    private String algorithm = HMAC_MD5;
   
    /**
     * Byte array that will represent the key matter
     */
    private byte[] keyVersionMatter;
   
    /**
     * Set the hash algorithm.
     *
     * @param hashAlgorithm Hash algorithm to use.
     * @return This object with algorithm updated.
     */
    public Builder algorithm(String hashAlgorithm) {
      if (hashAlgorithm.equalsIgnoreCase(HMAC_MD5)
          || hashAlgorithm.equalsIgnoreCase(HMAC_SHA1)
          || hashAlgorithm.equalsIgnoreCase(HMAC_SHA256)
          || hashAlgorithm.equalsIgnoreCase(HMAC_SHA384)
          || hashAlgorithm.equalsIgnoreCase(HMAC_SHA512)) {
        this.algorithm = hashAlgorithm;
        return this;
      } else {
        throw new IllegalArgumentException("Bad algorithm");
      }
    }

    /**
     * @param keyVersionMatter Byte array representing the key matter
     * @return This object with key matter set
     */
    public Builder matterVector(byte[] keyVersionMatter) {
      if (keyVersionMatter == null) {
        throw new NullPointerException("keyVersionMatter");
      }
      // set the key matter
      this.keyVersionMatter = keyVersionMatter;
      return this;
    }

    /**
     * @see KeyVersion.Builder#withData(KeyVersionData, ExtensionRegistry)
     */
    @Override
    public Builder withData(KeyVersionData kvData, ExtensionRegistry registry)
        throws InvalidProtocolBufferException {
      super.withData(kvData, registry);

      @SuppressWarnings("unused")
      HmacKeyVersionData data =
          kvData.getExtension(HmacKeyVersionData.extension);
      // TODO(darylseah): Extract info from data (currently not used)
     
      return this;
    }

    /**
     * @see KeyVersion.Builder#withCore(KeyVersionCore)
     */
    @Override
    protected Builder withCore(KeyVersionCore kvCore)
        throws InvalidProtocolBufferException {
      super.withCore(kvCore);
     
      HmacKeyVersionCore core =
          kvCore.getExtension(HmacKeyVersionCore.extension);
      // Extract info from core
      this.matterVector(core.getMatter().toByteArray());
      switch (core.getAlgorithm()) {
        case MD5:
          this.algorithm(HMAC_MD5);
          break;
        case SHA1:
          this.algorithm(HMAC_SHA1);
          break;
        case SHA2_256:
          this.algorithm(HMAC_SHA256);
          break;
        case SHA2_384:
          this.algorithm(HMAC_SHA384);
          break;
        case SHA2_512:
          this.algorithm(HMAC_SHA512);
          break;
        default:
          throw new IllegalArgumentException("Bad algorithm");
      }
     
      return this;
    }

    /**
     * Method to build a new HMACKeyVersion
     *
     * @return A HMACKeyVersion with the parameters set from the builder
     * @throws BuilderException
     */
    @Override
    public HMACKeyVersion build() throws BuilderException {
      try {
        return new HMACKeyVersion(this);
      } catch (Exception e) {
        throw new BuilderException("Building HMACKeyVersion failed", e);
      }
    }
  }
}
TOP

Related Classes of com.google.k2crypto.keyversions.HMACKeyVersion$Builder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.