基于HMACSHA1 加密算法的签名、校验JAVA示例

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 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);
    }
}

你可能感兴趣的:(基于HMACSHA1 加密算法的签名、校验JAVA示例)