com.siashan.toolkit.crypt.digest.HmacUtil Maven / Gradle / Ivy
package com.siashan.toolkit.crypt.digest;
import com.siashan.toolkit.crypt.binary.Hex;
import com.siashan.toolkit.crypt.util.StringUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.ByteBuffer;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/**
* Hmac算法工具类
*
* @author siashan
* @since 1.0.7
*/
public final class HmacUtil {
/**
* 流缓冲大小
*/
private static final int STREAM_BUFFER_LENGTH = 1024;
/**
* Mac实例
*/
private final Mac mac;
//--------------------------------------------- 构造方法 ------------------------------------------------------------//
/**
* 构造方法
*
* @param mac Mac实例
*/
private HmacUtil(final Mac mac) {
this.mac = mac;
}
/**
* 构造方法
*
* @param algorithm 算法名称
* @param key 秘钥
* @since 1.0.7
*/
public HmacUtil(final String algorithm, final byte[] key) {
this(getInitializedMac(algorithm, key));
}
/**
* 构造方法
*
* @param algorithm 算法名称
* @param key 秘钥
* @since 1.0.7
*/
public HmacUtil(final String algorithm, final String key) {
this(algorithm, StringUtils.getBytesUtf8(key));
}
/**
* 构造方法
*
* @param algorithm 算法名称
* @param key 秘钥
* @since 1.0.7
*/
public HmacUtil(final HmacAlgorithm algorithm, final String key) {
this(algorithm.getName(), StringUtils.getBytesUtf8(key));
}
/**
* 构造方法
*
* @param algorithm 算法名称
* @param key 秘钥
* @since 1.0.7
*/
public HmacUtil(final HmacAlgorithm algorithm, final byte[] key) {
this(algorithm.getName(), key);
}
/**
* 判断hmac算法是否可用
*
* @param name hmac算法名称
* @return 是否可用
* @since 1.0.7
*/
public static boolean isAvailable(final String name) {
try {
Mac.getInstance(name);
return true;
} catch (final NoSuchAlgorithmException e) {
return false;
}
}
/**
* 判断hmac算法是否可用
*
* @param name hmac算法
* @return 是否可用
* @since 1.0.7
*/
public static boolean isAvailable(final HmacAlgorithm name) {
return isAvailable(name.getName());
}
/**
* 获取Mac实例
*
* @param algorithm 算法
* @param key 秘钥
* @return Mac 实例
* @since 1.0.7
*/
public static Mac getInitializedMac(final HmacAlgorithm algorithm, final byte[] key) {
return getInitializedMac(algorithm.getName(), key);
}
/**
* 获取Mac实例
*
* @param algorithm 算法
* @param key 秘钥
* @return Mac 实例
* @since 1.0.7
*/
public static Mac getInitializedMac(final String algorithm, final byte[] key) {
if (key == null) {
throw new IllegalArgumentException("Null key");
}
try {
final SecretKeySpec keySpec = new SecretKeySpec(key, algorithm);
final Mac mac = Mac.getInstance(algorithm);
mac.init(keySpec);
return mac;
} catch (final NoSuchAlgorithmException e) {
throw new IllegalArgumentException(e);
} catch (final InvalidKeyException e) {
throw new IllegalArgumentException(e);
}
}
//--------------------------------------- 更新 Mac ------------------------------------------------------------------//
/**
* 重置并更新Mac
*
* @param mac Mac实例
* @param valueToDigest 用于更新{@link Mac}的值
* @return 更新后的Mac
*/
public static Mac updateHmac(final Mac mac, final byte[] valueToDigest) {
mac.reset();
mac.update(valueToDigest);
return mac;
}
/**
* 重置并更新Mac
*
* @param mac Mac实例
* @param valueToDigest 用于更新{@link Mac}的值
* @return 更新后的Mac
* @throws IOException IO异常
*/
public static Mac updateHmac(final Mac mac, final InputStream valueToDigest) throws IOException {
mac.reset();
final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
int read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH);
while (read > -1) {
mac.update(buffer, 0, read);
read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH);
}
return mac;
}
/**
* 重置并更新Mac
*
* @param mac Mac实例
* @param valueToDigest 用于更新{@link Mac}的值
* @return 更新后的Mac
* @throws IOException IO异常
*/
public static Mac updateHmac(final Mac mac, final String valueToDigest) {
mac.reset();
mac.update(StringUtils.getBytesUtf8(valueToDigest));
return mac;
}
//--------------------------------------------- hmac ---------------------------------------------------------------//
/**
* hmac算法.
*
* @param valueToDigest 要加密的值
* @return 加密后的值
* @since 1.0.7
*/
public byte[] hmac(final byte[] valueToDigest) {
return mac.doFinal(valueToDigest);
}
/**
* hmac算法.
*
* @param valueToDigest 要加密的值
* @return 加密后的值
* @since 1.0.7
*/
public String hmacHex(final byte[] valueToDigest) {
return Hex.encodeHexString(hmac(valueToDigest));
}
/**
* hmac算法.
*
* @param valueToDigest 要加密的值
* @return 加密后的值
* @since 1.0.7
*/
public byte[] hmac(final String valueToDigest) {
return mac.doFinal(StringUtils.getBytesUtf8(valueToDigest));
}
/**
* hmac算法.
*
* @param valueToDigest 要加密的值
* @return 加密后的值
* @since 1.0.7
*/
public String hmacHex(final String valueToDigest) {
return Hex.encodeHexString(hmac(valueToDigest));
}
/**
* hmac算法.
*
* @param valueToDigest 要加密的值
* @return 加密后的值
* @since 1.0.7
*/
public byte[] hmac(final ByteBuffer valueToDigest) {
mac.update(valueToDigest);
return mac.doFinal();
}
/**
* hmac算法.
*
* @param valueToDigest 要加密的值
* @return 加密后的值
* @since 1.0.7
*/
public String hmacHex(final ByteBuffer valueToDigest) {
return Hex.encodeHexString(hmac(valueToDigest));
}
/**
* hmac算法.
*
* @param valueToDigest 要加密的值
* @return 加密后的值
* @throws IOException IO异常
* @since 1.0.7
*/
public byte[] hmac(final InputStream valueToDigest) throws IOException {
final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
int read;
while ((read = valueToDigest.read(buffer, 0, STREAM_BUFFER_LENGTH)) > -1) {
mac.update(buffer, 0, read);
}
return mac.doFinal();
}
/**
* hmac算法.
*
* @param valueToDigest 要加密的值
* @return 加密后的值
* @throws IOException IO异常
* @since 1.0.7
*/
public String hmacHex(final InputStream valueToDigest) throws IOException {
return Hex.encodeHexString(hmac(valueToDigest));
}
/**
* hmac算法.
*
* @param valueToDigest 要加密的值
* @return 加密后的值
* @throws IOException IO异常
* @since 1.0.7
*/
public byte[] hmac(final File valueToDigest) throws IOException {
try (final BufferedInputStream stream = new BufferedInputStream(new FileInputStream(valueToDigest))) {
return hmac(stream);
}
}
/**
* hmac算法.
*
* @param valueToDigest 要加密的值
* @return 加密后的值
* @throws IOException IO异常
* @since 1.0.7
*/
public String hmacHex(final File valueToDigest) throws IOException {
return Hex.encodeHexString(hmac(valueToDigest));
}
}