基于HMACSHA1 加密算法的签名、校验JAVA示例
2018-10-13 本文已影响0人
倦鸟余花lee
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.lang3.StringUtils;
/**
* @description: 签名、校验接口
* @author lee
* @date 2018-10-13 下午2:22:40
*/
public class SignatrueTest {
private static Map<String, String> appSecretkey = new HashMap<>();
public static final String MAC_ALGORITHM_DEFAULT = "HmacSHA1";
public static void main(String[] args) {
// 第一步:为每一个应用分配一个secretKey,共享给发送方和接受方
String appId = "atp";
String secretKey = getSecretKey(appId);
// 第二步:发送方将待发送消息用HMACSHA1算法进行签名
String msg = "hello world";
String signatrue = getSignature(msg, secretKey);
// 第三步:将消息和签名结果同时传送,接收方进行校验签名
assert(verifySignature(appId, signatrue, msg));
}
/**
* 为每个appid生成唯一的secret_key(签名密钥)
* @param appId 应用唯一标识
* @return
*/
public static String getSecretKey(String appId) {
String secretKey = UUID.randomUUID().toString().replaceAll("-", "");
appSecretkey.put(appId, secretKey);
return secretKey;
}
/**
* 对消息进行签名
* @param msg 消息内容
* @param secretKey 签名密钥
* @return
*/
public static String getSignature(String msg, String secretKey) {
return hamcsha1(msg.getBytes(), secretKey.getBytes());
}
/**
* 获取基于哈希的消息验证代码
* @param data 消息内容字节数组
* @param key 签名密钥字节数组
* @return
*/
private static String hamcsha1(byte[] data, byte[] key) {
try {
SecretKeySpec signingKey = new SecretKeySpec(key, MAC_ALGORITHM_DEFAULT);
Mac mac = Mac.getInstance(MAC_ALGORITHM_DEFAULT);
mac.init(signingKey);
return byte2hex(mac.doFinal(data));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
/**
* 字节数组转16进制
* @param b 字节数组
* @return
*/
public static String byte2hex(byte[] b) {
StringBuilder hs = new StringBuilder();
String stmp;
for (int n = 0; b != null && n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0XFF);
if (stmp.length() == 1) {
hs.append('0');
}
hs.append(stmp);
}
return hs.toString().toUpperCase();
}
/**
* 接受方校验签名
* @param appId 应用唯一标识
* @param signatrue 签名结果
* @param msg 消息内容
* @return
*/
public static boolean verifySignature(String appId, String signatrue, String msg) {
String secretKey = appSecretkey.get(appId);
if (StringUtils.isBlank(secretKey)) {
return false;
}
String checkSignatrue = hamcsha1(msg.getBytes(), secretKey.getBytes());
return checkSignatrue.equals(checkSignatrue);
}
}