【kong系列八】之HMAC认证hmac-auth插件 - Go语言中文社区

【kong系列八】之HMAC认证hmac-auth插件


HMAC认证


hmac 插件


构造签名header

Authorization: hmac username="userhmac", algorithm="hmac-sha1", headers="X-Date Content-md5", signature="LqkezHTAuk/Sk3RTbguHHYZGt/8="

X-Date: Mon, 31 Jul 2017 07:23:02 GMT

Content-md5: IgWlVHazOsGgHGVlcKvQDA==



执行结果:成功


详解:Base64(HMAC-SHA1(signing string))加密详解:

一、事先准备加密工具HmacSha1Util Md5Util

1).编写HMacSha1Util.java,参看附1内容。

2).编写Md5Util,参考附2内容。

3).准备mac用户和密钥: username=userhmacsecret=zcy@0808

二、计算hmac签名

1).计算body Content-md5.

2).构建待签名报文String content = stb.append("X-Date: ").append(hdate).append("n").append("Content-md5: ").append(contentMD5).toString(); //注意 X-Date: 后有一个空格,紧接着才是US GMT时间。

3).构建签名String signature = BASE64.encode(HmacSha1Util.signatureReturnBytes(content, secret));

详细请参看附3 HmacTest.java

根据HmacTest.test1()方法执行的结果输出:

15:25:07.774 [main] INFO  com.kong.test.hmac.HmacTest - Content-md5: IgWlVHazOsGgHGVlcKvQDA==

15:25:07.793 [main] INFO  com.kong.test.hmac.HmacTest - X-Date: Mon, 31 Jul 2017 07:25:07 GMT

15:25:07.794 [main] INFO  com.kong.test.hmac.HmacTest -签名前内容: X-Date: Mon, 31 Jul 2017 07:25:07 GMT

Content-md5: IgWlVHazOsGgHGVlcKvQDA==

15:25:08.557 [main] INFO  com.kong.test.hmac.HmacTest -显示指定编码[推荐]: p4sGy3B+J/Zqt7gaLJVZCzVY5/Y=

将以上内容输出结果,按下文格式构建request报文。

三、构建request报文:

设置headers

Authorization:hmac username="userhmac", algorithm="hmac-sha1", headers="X-Date Content-md5", signature="p4sGy3B+J/Zqt7gaLJVZCzVY5/Y="

X-Date:Mon, 31 Jul 2017 07:25:07 GMT

Content-md5:IgWlVHazOsGgHGVlcKvQDA==


四、验证结果

如下图,正常返回,hamc加密认证成功。




1 HmacSha1Util.java

package com.kong.test.hmac;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;

/**
 * @Author changle
 * @Time 17/7/23.
 * @Desc 计算hmac签名
 */
public class HmacSha1Util {
    private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
    private static String toHexString(byte[] bytes) {
        Formatter formatter = new Formatter();
        for (byte b : bytes) {
            formatter.format("%02x", b);
        }
        return formatter.toString();
    }

    public static String signature(String data, String key) throws NoSuchAlgorithmException, InvalidKeyException {
        SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
        Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
        mac.init(signingKey);
        return toHexString(mac.doFinal(data.getBytes()));
    }

    public static byte[] signatureReturnBytes(String data, String key) throws NoSuchAlgorithmException, InvalidKeyException {
        SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
        Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
        mac.init(signingKey);
        return mac.doFinal(data.getBytes());
    }

    public static void main(String[] args) throws Exception {
        String hmac = signature("data", "f96384947e0f4de39d3ffef6bd12c551");
        assert hmac.equals("104152c5bfdca07bc633eebd46199f0255c9f49d");
    }
}



2 Md5Util.java

package com.kong.test.hmac;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Md5Util {
    public static String md5(String param) {
        if (StringUtils.isBlank(param)) {
            throw new IllegalArgumentException("param can not be null");
        }
        try {
            byte[] bytes = param.getBytes("utf-8");
            final MessageDigest md = MessageDigest.getInstance("MD5");
            md.reset();
            md.update(bytes);
            final Base64 base64 = new Base64();
            final byte[] enbytes = base64.encode(md.digest());
            return new String(enbytes);
        } catch (final NoSuchAlgorithmException e) {
            throw new IllegalArgumentException("unknown algorithm MD5");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}



3 HmacTest.java 计算mac签名:

package com.kong.test.hmac;

import lombok.extern.slf4j.Slf4j;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**
 * @Author changle
 * @Time 17/7/19.
 * @Desc HMac加密签名验证.
 */
@Slf4j
public class HmacTest {
    public static void main(String[] args) {
        test1();
    }

    static void test1(){
        String queryParam = "/testHmac/qryParam=test1&pageNo=1";
        String contentMD5 = Md5Util.md5(queryParam);
        log.info("Content-md5: {}", contentMD5);

        Date d=new Date();
        DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String hdate = format.format(d);
        log.info("X-Date: {}",hdate);

        StringBuilder stb = new StringBuilder();
        String content = stb.append("X-Date: ").append(hdate).append("n").append("Content-md5: ").append(contentMD5).toString();
        log.info("签名前内容: "+content);
        String secret = "zcy@0808";  //用户userhmac的密钥
        try {
            String signature2 = new String(Base64.getEncoder().encode(HmacSha1Util.signatureReturnBytes(content, secret)), "US-ASCII");
            log.info("显示指定编码[推荐]: {}", signature2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}


版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/li396864285/article/details/77372667
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 19:59:37
  • 阅读 ( 1507 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢