JWT Token的生成和解析及MD5加/解密

jwt Token生成工具类, 及MD5加密解密工具类

  1. 生成的工具类, 网上很多; 我记录下我用的, 代码如下:

JwtToken类

package com.common;


import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

/**
 * APP登录Token的生成和解析
 */
public class JwtToken {

    /** token秘钥,请勿泄露,请勿随便修改 backups:SECRETKey */
    public static final String SECRET = "SECRETKey"; //这里是我随便填的, 用的时候要修改
    /** token 过期时间: 10天 */
    public static final int  CALENDARFIELD = Calendar.DATE;
    public static final int  CALENDARINTERVAL = 10;

    /**
     * JWT生成Token.<br/>
     * JWT构成: header, payload, signature
     * @param user_id
     *	 登录成功后用户user_id, 参数user_id不可传空
     */
    public static String createToken(String userJson) throws Exception {
        userJson = AesEncryption.encrypt(userJson);
        Date iatDate = new Date();
        // expire time
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(CALENDARFIELD, CALENDARINTERVAL);
        Date expiresDate = nowTime.getTime();
        // header Map
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("alg", "HS256");
        map.put("typ", "JWT");
        String token = JWT.create().withHeader(map) // heade
                .withClaim("iss", "Service") // payload
                .withClaim("aud", "APP").withClaim("user", null == userJson ? null : userJson)
                .withIssuedAt(iatDate) // sign time
                .withExpiresAt(expiresDate) // expire time
                .sign(Algorithm.HMAC256(SECRET)); // signature
        return token;
    }

    /**
     *	 解密Token
     * @param token
     * @return
     * @throws Exception
     */
    public static Map<String, Claim> verifyToken(String token) {
        DecodedJWT jwt = null;
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
            jwt = verifier.verify(token);
        } catch (Exception e) {
            e.printStackTrace();// token 校验失败, 抛出Token验证非法异常
        }
        return jwt.getClaims();
    }

    /**
     * 	根据Token获取user
     * @param token
     * @return user
     * @throws Exception
     */
    public static String getUser(String token) throws Exception {
        Map<String, Claim> claims = verifyToken(token);
        Claim userClaim = claims.get("user");
        if (null == userClaim || StringUtils.isEmpty(userClaim.asString())) {
            new Exception("token 校验失败, Token验证非法异常");
            // token 校验失败, 抛出Token验证非法异常
        }
        return AesEncryption.desencrypt(userClaim.asString());
    }

}


AES加密,解密

package com.common;

import com.util.MD5Utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AesEncryption {

    private static final String KEY = "aaaa123456"; // 用的时候要修改
    private static final String IV = "aaaa123456"; // 用的时候要修改

    /**
     * 加密
     * @param data
     * @return
     * @throws Exception
     */
    public static String encrypt(String data) throws Exception {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            int blockSize = cipher.getBlockSize();
            byte[] dataBytes = data.getBytes("UTF-8");
            int plaintextLength = dataBytes.length;
            if ((plaintextLength == 96) || (plaintextLength % blockSize != 0)) {// 96刚好加密大于128位
                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
            }
            byte[] plaintext = new byte[plaintextLength];
            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
            SecretKeySpec keyspec = new SecretKeySpec(KEY.getBytes(), "AES");
            IvParameterSpec ivspec = new IvParameterSpec(IV.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
            byte[] encrypted = cipher.doFinal(plaintext);
            return Base64Method.encryptBase64(encrypted);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 解密
     * @param data
     * @return
     * @throws Exception
     */
    public static String desencrypt(String data) {
        try {
            byte[] encrypted1 = Base64Method.decryptBase64ForByte(data);
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            SecretKeySpec keyspec = new SecretKeySpec(KEY.getBytes(), "AES");
            IvParameterSpec ivspec = new IvParameterSpec(IV.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
            byte[] rawOriginal = cipher.doFinal(encrypted1);
            byte[] original = new String(rawOriginal).replaceAll("\0", "").getBytes();
            String originalString = new String(original, "UTF-8");
            return originalString;
        } catch (Exception e) {
            System.out.println("密码解密异常===================");
            return null;
        }
    }

//需要的时候用主方法, 看自己的密码加解密后是什么
    public static void main(String[] args) throws Exception {
//		String pwd = "password";
//		String str = AesEncryption.encrypt(pwd);
//		System.out.println("加密后:" + str);
//		System.out.println("解密后:" + AesEncryption.desencrypt(str));
//		System.out.println("MD5加密后:" + MD5Utils.generate(pwd));
    }
}

Base64Method类

package com.common;

import java.io.IOException;

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

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class Base64Method {

    public static String encryptBase64(String strString) throws Exception {
        Base64 base64 = new Base64();
        String base64str = new String(base64.encode(strString.getBytes("utf-8")), "utf-8");
        base64str = base64str.replace("\n", "").replace("\r", "").replace('+', '-').replace('/', '_');
        return base64str;
    }

    public static String encryptBase64(byte[] bytes) throws Exception {
        Base64 base64 = new Base64();
        String base64str = new String(base64.encode(bytes), "utf-8");
        base64str = base64str.replace("\n", "").replace("\r", "").replace('+', '-').replace('/', '_');
        return base64str;
    }

    public static String decryptBase64(String strString) throws Exception {
        Base64 base64 = new Base64();
        byte[] bytes = base64.decode(strString.replace('-', '+').replace('_', '/').getBytes("utf-8"));
        String str = new String(bytes, "utf-8");
        return str;
    }

    public static byte[] decryptBase64ForByte(String strString) throws Exception {
        Base64 base64 = new Base64();
        byte[] bytes = base64.decode(strString.replace('-', '+').replace('_', '/').getBytes("utf-8"));
        return bytes;
    }

    public static byte[] safeUrlBase64Decode(final String safeBase64Str) throws IOException {
        String base64Str = safeBase64Str.replace('-', '+');
        base64Str = base64Str.replace('_', '/');
        int mod4 = base64Str.length() % 4;
        if (mod4 > 0) {
            base64Str = base64Str + "====".substring(mod4);
        }
        return new BASE64Decoder().decodeBuffer(base64Str);
    }

    public static String safeUrlBase64Encode(byte[] data) {
        String encodeBase64 = new BASE64Encoder().encode(data);
        String safeBase64Str = encodeBase64.replace('+', '-');
        safeBase64Str = safeBase64Str.replace('/', '_');
        safeBase64Str = safeBase64Str.replaceAll("=", "");
        return safeBase64Str;
    }

}

3. 上面代码使用了Cipher类实现加密

可以看我转载的一个文章, 链接: https://blog.csdn.net/weixin_45305706/article/details/106378476.

MD5Utils工具类

package com.util;

import org.apache.commons.codec.binary.Hex;

import java.security.MessageDigest;
import java.util.Random;

public class MD5Utils {

    private static final String[] hexDigIts = {"s","e","c","r","e","t","k","e","y","1","2","3","4","5","6","7"}; // 用的时候要修改, 长短也不是固定的, 随意改

    /**
     * 	生成含有随机盐的密码
     */
    public static String generate(String password) {
        Random r = new Random();
        StringBuilder sb = new StringBuilder(16);
        sb.append(r.nextInt(99999999)).append(r.nextInt(99999999));
        int len = sb.length();
        if (len < 16) {
            for (int i = 0; i < 16 - len; i++) {
                sb.append("0");
            }
        }
        String salt = sb.toString();
        password = md5Hex(password + salt);
        char[] cs = new char[48];
        for (int i = 0; i < 48; i += 3) {
            cs[i] = password.charAt(i / 3 * 2);
            char c = salt.charAt(i / 3);
            cs[i + 1] = c;
            cs[i + 2] = password.charAt(i / 3 * 2 + 1);
        }
        return new String(cs);
    }

    /**
     * 校验密码是否正确
     */
    public static boolean verify(String password, String md5) {
        char[] cs1 = new char[32];
        char[] cs2 = new char[16];
        for (int i = 0; i < 48; i += 3) {
            cs1[i / 3 * 2] = md5.charAt(i);
            cs1[i / 3 * 2 + 1] = md5.charAt(i + 2);
            cs2[i / 3] = md5.charAt(i + 1);
        }
        String salt = new String(cs2);
        return md5Hex(password + salt).equals(new String(cs1));
    }

    /**
     * 获取十六进制字符串形式的MD5摘要
     */
    public static String md5Hex(String src) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] bs = md5.digest(src.getBytes());
            return new String(new Hex().encode(bs));
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * MD5加密
     * @param origin 字符
     * @param charsetname 编码
     * @return
     */
    public static String MD5Encode(String origin, String charsetname){
        String resultString = null;
        try{
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if(null == charsetname || "".equals(charsetname)){
                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
            }else{
                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
            }
        }catch (Exception e){
        }
        return resultString;
    }

    public static String byteArrayToHexString(byte b[]){
        StringBuffer resultSb = new StringBuffer();
        for(int i = 0; i < b.length; i++){
            resultSb.append(byteToHexString(b[i]));
        }
        return resultSb.toString();
    }

    public static String byteToHexString(byte b){
        int n = b;
        if(n < 0){
            n += 256;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigIts[d1] + hexDigIts[d2];
    }

//需要的时候, 可以用主方法测试一下
    /*
     * public static void main(String[] args) {
     * System.out.println(generate("abcd@zand")); // 用的时候要修改
     * //BigDecimal as = new BigDecimal("0"); 
     * //String md = generate("110.01"); // 用的时候要修改
     * //System.out.println(md);
     * //System.out.println(verify("110.01",md));
     * //System.out.println(generate(as.toString())); }
     */

}

  1. 以上的代码, 稍稍修改就能用;
  2. 有兴趣的, 请提出问题, 一起交流;
  3. 下一篇记录zuul网关的使用;
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值