All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.oauth.jsontoken.crypto.HmacSHA256Verifier Maven / Gradle / Ivy

/**
 * Copyright 2010 Google Inc.
 *
 * 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 net.oauth.jsontoken.crypto;

import java.security.InvalidKeyException;
import java.security.SignatureException;
import java.util.Arrays;

/**
 * A {@link Verifier} that uses HMAC-SHA256 to verify symmetric-key signatures on byte arrays.
 */
public class HmacSHA256Verifier implements Verifier {

  private final HmacSHA256Signer signer;

  /**
   * Public constructor.
   * @param verificationKey the HMAC verification key to be used for signature verification.
   * @throws InvalidKeyException if the verificationKey cannot be used as an HMAC key.
   */
  public HmacSHA256Verifier(byte[] verificationKey) throws InvalidKeyException {
    signer = new HmacSHA256Signer("verifier", null, verificationKey);
  }

  /*
   * (non-Javadoc)
   * @see net.oauth.jsontoken.crypto.Verifier#verifySignature(byte[], byte[])
   */
  @Override
  public void verifySignature(byte[] source, byte[] signature) throws SignatureException {
    byte[] comparison = signer.sign(source);
    if (!compareBytes(signature, comparison)) {
      throw new SignatureException("signature did not verify");
    }
  }

  /**
   * Performs a byte-by-byte comparison of {@code first} and {@code second} parameters. This
   * method will "NOT" short-circuit the comparison once it has detected a byte difference in
   * order to defend against a "timing attack".
   *
   * @param first the first byte array used in the comparison
   * @param second the second byte array used in the comparison
   * @return {@code true} if the {@code first} and {@code second} byte arrays are equal
   *         otherwise {@code false}
   */
  private boolean compareBytes(byte[] first, byte[] second) {
    if (first == null || second == null) {
      return (first == second);
    } else if (first.length != second.length) {
      return false;
    } else {
      byte result = 0;
      for (int i = 0; i < first.length; i++) {
        result |= first[i] ^ second[i];
      }
      return (result == 0);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy