社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
构造签名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))加密详解:
1).编写HMacSha1Util.java,参看附1内容。
2).编写Md5Util,参考附2内容。
3).准备mac用户和密钥: username=userhmac,secret=zcy@0808
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报文。
设置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();
}
}
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!