package org.araqne.storage.crypto.impl;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.araqne.storage.crypto.LogCryptoException;
import org.araqne.storage.crypto.MacBuilder;
public class JavaMacBuilder implements MacBuilder {
private String algorithm;
private byte[] digestKey;
private ThreadLocal<Mac> c;
private SecretKeySpec digestKeySpec;
public JavaMacBuilder(String algorithm, byte[] digestKey) throws LogCryptoException {
if (algorithm == null || digestKey == null)
throw new LogCryptoException("null hmac algorithm or key");
this.algorithm = algorithm;
this.digestKey = digestKey;
try {
// test if algorithm is available
Mac.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
throw new LogCryptoException(algorithm, e);
}
c = new ThreadLocal<Mac>() {
@Override
protected Mac initialValue() {
try {
return Mac.getInstance(JavaMacBuilder.this.algorithm);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException(e);
}
}
};
digestKeySpec = new SecretKeySpec(digestKey, algorithm);
}
@Override
public byte[] digest(byte[] input) throws LogCryptoException {
if (digestKey == null)
throw new IllegalArgumentException("cipher key is not supplied");
try {
c.get().init(digestKeySpec);
return c.get().doFinal(input);
} catch (InvalidKeyException e) {
throw new LogCryptoException(algorithm, e);
}
}
@Override
public byte[] digest(byte[] input, int offset, int limit) throws LogCryptoException {
if (digestKey == null)
throw new IllegalArgumentException("cipher key is not supplied");
try {
c.get().init(digestKeySpec);
c.get().update(input, offset, limit);
return c.get().doFinal();
} catch (InvalidKeyException e) {
throw new LogCryptoException(algorithm, e);
}
}
}