jwt token实现rs256非对称算法demo

package com.example.demo;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.signers.JWTSignerUtil;

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName: demo
 * @Description:
 * @Author bellaaaaa
 * @Date 2023/2/13
 * @Version 1.0
 */
public class demo {

    public static final String ENCRYPT_TYPE = "RSA";

    /**
     * 获取公钥的key
     */
    private static final String PUBLIC_KEY = "RSAPublicKey";
    private static final String PUBLIC_KEY_STR = "RSAPublicKeyStr";

    /**
     * 获取私钥的key
     */
    private static final String PRIVATE_KEY = "RSAPrivateKey";
    private static final String PRIVATE_KEY_STR = "RSAPrivateKeyStr";

    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //rs256生成公私秘钥
        Map<String, Object> keyPairMap = generateKeyPair();
        String RSAPublicKeyStr = (String) keyPairMap.get(PUBLIC_KEY_STR);
        String RSAPrivateKeyStr = (String) keyPairMap.get(PRIVATE_KEY_STR);


        Map<String,Object> map = new HashMap<String,Object>(){{
            String guid = "cn";
            put("guid",guid);
            put("iat",System.currentTimeMillis()+1000*60*60);
        }};

        //私钥加密token签名
        PrivateKey RSAPrivateKey = getPrivateKey(RSAPrivateKeyStr);
        String token = JWTUtil.createToken(map, JWTSignerUtil.rs256(RSAPrivateKey));
        System.out.println("token:"+token);

        //rs256公钥验签
        PublicKey publicKey = getPublicKey(RSAPublicKeyStr);
        boolean b = JWTUtil.verify(token, JWTSignerUtil.rs256(publicKey));
        System.out.println("rs256验签:"+b);

        //解析token
        JWT jwt = JWTUtil.parseToken(token);
        System.out.println(jwt.getPayload());
    }


    /**
     * 字符串转私钥
     * @param RSAPrivateKeyStr
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    private static PrivateKey getPrivateKey(String RSAPrivateKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] encodedKey = Base64.getDecoder().decode(RSAPrivateKeyStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
        KeyFactory keyFactory = KeyFactory.getInstance(ENCRYPT_TYPE);
        PrivateKey publicKey = keyFactory.generatePrivate(keySpec);
        return publicKey;
    }

    /**
     * 公钥字符串转化publicKey
     * @param RSAPublicKeyStr
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    private static PublicKey getPublicKey(String RSAPublicKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
        X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(RSAPublicKeyStr));
        KeyFactory keyFactory = KeyFactory.getInstance(ENCRYPT_TYPE);
        PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
        return publicKey;
    }

    public static Map<String, Object> generateKeyPair() {
        try {
            KeyPair pair = SecureUtil.generateKeyPair(ENCRYPT_TYPE);
            PrivateKey privateKey = pair.getPrivate();
            PublicKey publicKey = pair.getPublic();
            // 获取 公钥和私钥 的 编码格式(通过该 编码格式 可以反过来 生成公钥和私钥对象)
            byte[] pubEncBytes = publicKey.getEncoded();
            byte[] priEncBytes = privateKey.getEncoded();

            // 把 公钥和私钥 的 编码格式 转换为 Base64文本 方便保存
            String pubEncBase64 = Base64.getEncoder().encodeToString(pubEncBytes);
            String priEncBase64 = Base64.getEncoder().encodeToString(priEncBytes);

            Map<String, Object> map = new HashMap<>(4);
            map.put(PUBLIC_KEY_STR, pubEncBase64);
            map.put(PRIVATE_KEY_STR, priEncBase64);
            map.put(PUBLIC_KEY, publicKey);
            map.put(PRIVATE_KEY, privateKey);

            return map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值