/**
* 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.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* A signer that can sign byte arrays using HMAC-SHA256.
*/
public class HmacSHA256Signer extends AbstractSigner {
private static final String HMAC_SHA256_ALG = "HmacSHA256";
private final Mac hmac;
private final SecretKey signingKey;
/**
* Public constructor.
* @param issuer the id of this signer, to be included in the envelope of the JSON token.
* @param keyId the id of the key that will be included in the envelope. If null, will be omitted
* from the envelope.
* @param keyBytes the actual key.
* @throws InvalidKeyException if the key cannot be used as an HMAC key.
*/
public HmacSHA256Signer(String issuer, String keyId, byte[] keyBytes) throws InvalidKeyException {
super(issuer, keyId);
this.signingKey = new SecretKeySpec(keyBytes, HMAC_SHA256_ALG);
try {
this.hmac = Mac.getInstance(HMAC_SHA256_ALG);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("cannot use Hmac256Signer on system without HmacSHA256 alg", e);
}
// just to make sure we catch invalid keys early, let's initialize the hmac and throw if something goes wrong
hmac.init(signingKey);
}
/*
* (non-Javadoc)
* @see net.oauth.jsontoken.crypto.Signer#sign(byte[])
*/
@Override
public byte[] sign(byte[] source) {
try {
hmac.init(signingKey);
} catch (InvalidKeyException e) {
// this should not happen - we tested this in the constructor
throw new IllegalStateException("key somehow became invalid since calling the constructor", e);
}
return hmac.doFinal(source);
}
/*
* (non-Javadoc)
* @see net.oauth.jsontoken.crypto.Signer#getSignatureAlgorithm()
*/
@Override
public SignatureAlgorithm getSignatureAlgorithm() {
return SignatureAlgorithm.HS256;
}
}