包含hmac-based和public-key emqx啟用JWT令牌認證( 二 )

開啟驗證

  • Secret,用于校驗簽名的密鑰,與生成簽名時使用的密鑰相同
  • Secret Base64 Encode,表明 Secret 是否經過 Base64 加密,即 EMQX 在使用 Secret 校驗簽名時是否需要先對其進行 Base64 解密

包含hmac-based和public-key emqx啟用JWT令牌認證

文章插圖
public-key方式驗證概述emqx中public-key方式,表明 JWT 使用私鑰生成簽名,需要使用公鑰校驗簽名(支持 RS256、RS384、RS512、ES256、ES384 和 ES512 算法),對于生成的JWT令牌來說,加密方式我這里換成了RSA,即SignatureAlgorithm.RS256
RS256("RS256", "RSASSA-PKCS-v1_5 using SHA-256", "RSA", "SHA256withRSA", true)其原理是對JWT令牌使用私鑰加簽,然后將公鑰配置在emqx上,連接時用emqx中的公鑰驗簽,防止信息被篡改
開啟驗證
  • Public Key,指定用于校驗簽名的 PEM 格式的公鑰
    包含hmac-based和public-key emqx啟用JWT令牌認證

    文章插圖
PEM格式的公鑰私鑰生成首先,需要在windows上安裝openssl,然后通過指令生成pem格式文件
    openssl生成私鑰命令: openssl genrsa -out rsa_private_key.pem 1024    openssl生成公鑰命令: openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
包含hmac-based和public-key emqx啟用JWT令牌認證

文章插圖
包含hmac-based和public-key emqx啟用JWT令牌認證

文章插圖
PEM格式的私鑰Java代碼中是沒辦法直接使用的,需要手動或者通過方法變成連續的字符串
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMGL0LhjNqcK32eTHLrmJovihQjIGYJrqw+GsAwgQxLq2SUZxEkbNNOK8OnR5S8g3PUdHraqWlthiLWLfZB3HjsIhq7if9giln9NkCs8hrbIxaghJTB3zo/L7+Bq2eL3zx5ke9ExceG9Xb7d5RCQ1d/xmzKNZqgC0tOGiiaLrU89AgMBAAECgYBhCNDu8MbgvqG80tOvnF2s+jdKbM/lREex9AvlOHOIU3fkkuOG5333pQwdnh7yHt7IgP36BLRiZibdJf8g46eif+Azf7nmH9fW4tQagdjoVoZGz+9Vp9m2ERRsy7Po50d4C5WQdKbxWiSE6qTWtrqIxpZCGkhPyuWsPaYNTQ2TXQJBAOSM1wFtXD3ivSS+SjgTessQdWHaK/xRvN+glr6JJhzK0Tl6xb8IftFJjBi4RY3e1eAciYVhnTDpQfhKGrRumVMCQQDYyrfldKPxXwWelAVbSAepOrU+Iod0DUKpCRS83dGMQFLI/fmAdNL2AY2drr3w6xdeAWTAagB4sKzWoyEMShMvAkEAr42PSUVbaR3U83hHQjOUSo5l27fduX5/eba8k7Z9U/hmJaSsaER6RQAdYI+KvaLA3diNuap1N7C0P6eMQ7QAiQJBAICYh0shzFnSLsgpL6A88uZsf7Qy0TyC3SbdzyJVRga25SR6mvSa18S7mSCO1fbBzSOjGfuVJWByFKRhMapTilsCQQCaVsZ/2QrlzeHaAfWbMSVi8ml3JlF1nCOyiNtypNJB+HXXrE6SJc3vRnwPIku1N6uduQF2W0ypykCzDdcqGkuFPEM格式中帶有換行符,處理時需要注意,此時連接的字符串就位私鑰
代碼package com.mio.mqtt.util;import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import sun.misc.BASE64Decoder;import java.security.KeyFactory;import java.security.spec.KeySpec;import java.security.spec.PKCS8EncodedKeySpec;import java.time.Instant;import java.util.Date;import java.util.HashMap;import java.util.Map;public class JWTUtils {    public static void main(String[] args) {        Instant now = Instant.now();        Map<String, Object> claims = new HashMap<>();        claims.put("user", "mqtt-client");        String privateKey = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMGL0LhjNqcK32eTHLrmJovihQjIGYJrqw+GsAwgQxLq2SUZxEkbNNOK8OnR5S8g3PUdHraqWlthiLWLfZB3HjsIhq7if9giln9NkCs8hrbIxaghJTB3zo/L7+Bq2eL3zx5ke9ExceG9Xb7d5RCQ1d/xmzKNZqgC0tOGiiaLrU89AgMBAAECgYBhCNDu8MbgvqG80tOvnF2s+jdKbM/lREex9AvlOHOIU3fkkuOG5333pQwdnh7yHt7IgP36BLRiZibdJf8g46eif+Azf7nmH9fW4tQagdjoVoZGz+9Vp9m2ERRsy7Po50d4C5WQdKbxWiSE6qTWtrqIxpZCGkhPyuWsPaYNTQ2TXQJBAOSM1wFtXD3ivSS+SjgTessQdWHaK/xRvN+glr6JJhzK0Tl6xb8IftFJjBi4RY3e1eAciYVhnTDpQfhKGrRumVMCQQDYyrfldKPxXwWelAVbSAepOrU+Iod0DUKpCRS83dGMQFLI/fmAdNL2AY2drr3w6xdeAWTAagB4sKzWoyEMShMvAkEAr42PSUVbaR3U83hHQjOUSo5l27fduX5/eba8k7Z9U/hmJaSsaER6RQAdYI+KvaLA3diNuap1N7C0P6eMQ7QAiQJBAICYh0shzFnSLsgpL6A88uZsf7Qy0TyC3SbdzyJVRga25SR6mvSa18S7mSCO1fbBzSOjGfuVJWByFKRhMapTilsCQQCaVsZ/2QrlzeHaAfWbMSVi8ml3JlF1nCOyiNtypNJB+HXXrE6SJc3vRnwPIku1N6uduQF2W0ypykCzDdcqGkuF";        try {            // 獲取秘鑰            BASE64Decoder base64Decoder=new BASE64Decoder();            byte[] bytes = base64Decoder.decodeBuffer(privateKey);            KeySpec spec = new PKCS8EncodedKeySpec(bytes);            KeyFactory keyFactory = KeyFactory.getInstance("RSA");            String compact = Jwts.builder()                    .setClaims(claims) // 自定義聲明                    .setIssuedAt(Date.from(now)) // 對標準中的聲明賦值,設置簽發時間                    .setExpiration(Date.from(now.plusSeconds(1000))) // 對標準中的聲明賦值,設置過期時間                    .signWith(SignatureAlgorithm.RS256, keyFactory.generatePrivate(spec)) // 設置簽名                    .compact();            System.out.println(compact);        } catch (Exception e) {            throw new RuntimeException(e);        }    }}

推薦閱讀