JWT和HMAC(AK/SK)认证方式的区别和使用场景

prerequisite: 什么是JWT?

JWT适用场景

  1. 用户登录:用户通过密码换取jwt,后续使用jwt继续交互,以实现一次登录访问全部资源的目的。
  2. 简单实体认证:由服务方直接分发一个生成的jwt给使用方,使用方每次使用jwt方位服务的接口。这种方式长用户接口之间的实体认证,但安全性较弱,因为其他方如果获知了jwt token,也依然能够通过该token访问接口。

HMAC(AK/SK)

简单介绍一下HMAC

HMAC(Hash-based Message Authentic Code),即基于hash的消息认证码,它使用哈希算法,以一个密钥和一个消息作为输入,生成一个消息摘要作为输出,服务端通过对比发送的摘要和自己生成的摘要是否相同完成认证。

HMAC(AK/SK)
HMAC预先生成一个access key(AK)和secure key(SK),然后客户端通过使用AK和SK以及可能存在的偏移量iv对一段消息文本进行签名,客户端发送AK和签名,服务端使用AK和SK以及偏移量iv重新签名,通过对比两个签名是否一致的方式完成认证请求。这种方式避免传输secure key,且大多数情况下只允许使用一次,避免了重放攻击。

JWT和HMAC的区别
  • HMAC服务端不仅有一个密钥,同时每一个调用实体都分发一个appid(AK)
  • 用来签名的数据可以由调用双方约定,简单可以使用字符串,也可以使用map、array等其他数据类型
  • 签名过程可以带上时间戳,这样每次调用的签名都不一样,安全性高
  • 签名是根据约定好的算法进行计算,不需要客户端获取token之后一直传递token,但每次调用都要进行签名,没有jwt计算轻量。

HMAC

适合api之间相互调用的认证

JWT使用HMAC签名

事实上两种方式经常结合使用,因为jwt的签名过程本质上和HMAC一样,都是进行一次hash计算。

方式一:jwt的签名过程中使用HMAC加密算法,后续持续使用token鉴权(token具有时效性,可以短时间内持续有效),这样既保证了安全,也不会有每调用一次就需要重新签名这样重复的计算量。

方式二:获取jwt签名后的token之后,在使用HMAC算法对该token进行签名,这样可以实现跨系统调用。

参考文献

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用EMQX的jwt认证方式调用/api/v5/authentication/{id}/users的java代码示例,请您参考: ``` import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Base64; import java.util.Date; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.json.JSONObject; public class EMQXApiCall { // EMQX相关信息 private static final String EMQX_HOST = "your-emqx-host"; private static final String EMQX_PORT = "your-emqx-port"; private static final String EMQX_API_URL = "http://" + EMQX_HOST + ":" + EMQX_PORT + "/api/v5/authentication/{id}/users"; private static final String EMQX_ID = "your-emqx-id"; // jwt相关信息 private static final String JWT_SECRET = "your-jwt-secret"; private static final String JWT_ISSUER = "your-jwt-issuer"; public static void main(String[] args) throws Exception { // 构建jwt String token = generateJwt(); // 构建Http请求 HttpClient httpClient = HttpClientBuilder.create().build(); HttpGet httpGet = new HttpGet(EMQX_API_URL); httpGet.setHeader("Authorization", "Bearer " + token); // 发送Http请求 HttpResponse response = httpClient.execute(httpGet); String responseBody = EntityUtils.toString(response.getEntity()); System.out.println(responseBody); } /** * 构建Jwt使用HmacSHA256加密方式。 */ private static String generateJwt() throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException { long timestamp = new Date().getTime() / 1000; String headerAndPayload = Base64.getUrlEncoder().encodeToString(("{\"alg\": \"HS256\", \"typ\": \"JWT\", \"iss\": \"" + JWT_ISSUER + "\", \"exp\": " + (timestamp + 3600) + "}").getBytes()) + "." + Base64.getUrlEncoder().encodeToString(("{\"client_id\": \"" + EMQX_ID + "\", \"scope\": \"mqtt.publish\", \"exp\": " + (timestamp + 3600) + "}").getBytes()); Mac hmac = Mac.getInstance("HmacSHA256"); hmac.init(new SecretKeySpec(JWT_SECRET.getBytes(), "HmacSHA256")); String signature = Base64.getUrlEncoder().encodeToString(hmac.doFinal(headerAndPayload.getBytes("UTF-8"))); return headerAndPayload + "." + signature; } } ``` 希望这段代码对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值