java 基于JWT的RSA数据加密生成token

引入maven依赖 

<!--jwt用户登录数据加密-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

<!-- 将RSA加密后的文件bytes 和 string 的相互转化 -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>2.9.9</version>
</dependency>


核心类

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import java.io.IOException;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
@Slf4j
public class RsaUtils {

    /**
     * 获取公钥对象
     *
     * @param publicKeyStr 公钥字符串常量
     * @return 公钥对象
     * @throws Exception
     */
    public static PublicKey getPublicKey(String publicKeyStr) throws Exception {
        byte[] bytes = Base64.decodeBase64(publicKeyStr);
        return getPublicKey(bytes);
    }

    /**
     * 获取私钥数据对象
     *
     * @param privateKeyStr 私钥字符串常量
     * @return 私钥对象
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(String privateKeyStr) throws Exception {
        byte[] bytes = Base64.decodeBase64(privateKeyStr);
        return getPrivateKey(bytes);
    }

    /**
     * 获取公钥
     *
     * @param bytes 公钥的字节形式
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKey(byte[] bytes) throws Exception {
        X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes);
        KeyFactory factory = KeyFactory.getInstance("RSA");
        return factory.generatePublic(spec);
    }

    /**
     * 获取密钥
     *
     * @param bytes 私钥的字节形式
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(byte[] bytes) throws Exception {
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
        KeyFactory factory = KeyFactory.getInstance("RSA");
        return factory.generatePrivate(spec);
    }


    /**
     * 根据密文,生成rsa公钥和私钥,并写入指定文件
     * @param publicKeyFilename 公钥文件路径
     * @param secret            生成密钥的密文
     * @throws Exception
     */
    public static void generateKey(String publicKeyFilename, String secret) throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        SecureRandom secureRandom = new SecureRandom(secret.getBytes());
        keyPairGenerator.initialize(2048, secureRandom);
        KeyPair keyPair = keyPairGenerator.genKeyPair();
        // 获取公钥并写出
        byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
//        keyMap.put(publicKeyFilename,publicKeyBytes);
    }


    /**
     * 根据密文,生成rsa公钥和私钥,并写入指定文件
     *
     * @param secret             生成密钥的密文
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    public static void generateKey(String secret) {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            SecureRandom secureRandom = new SecureRandom(secret.getBytes());
            keyPairGenerator.initialize(2048, secureRandom);
            KeyPair keyPair = keyPairGenerator.genKeyPair();
            // 获取公钥并写出
            byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
            String publicKeyStr = Base64.encodeBase64String(publicKeyBytes);
            log.info("publicKeyStr: " + publicKeyStr);
            log.info("===========================================================");

            // 获取私钥并写出
            byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
            String privateKeyStr = Base64.encodeBase64String(privateKeyBytes);
            log.info("privateKeyStr: " + privateKeyStr);

        } catch (Exception e) {
            log.error( "初始化公钥私钥异常: " + e.getMessage(),e);
        }
    }

    public static void main(String[] args) {
//        String secret = "zhou@LoginInfo(Auth}*^3256)&kong_local%";
//        String secret = "zhou@LoginInfo(Auth}*^3256)&kong_test%";
        String secret = "zhou@LoginInfo(Auth}*^6874)&kong_prod%";
        generateKey(secret);

    }

}

 

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;
import java.security.PrivateKey;
import java.security.PublicKey;
/**
 * @author zhoushisheng
 * 用户登录认证拦截
 */
@Slf4j
public class UserAuthenticationHandler implements HandlerInterceptor {

    private static ThreadLocal<UserInfo> tokenThread = new ThreadLocal<>();

    private static ThreadLocal<Boolean> interceptThread = new ThreadLocal<Boolean>();

    private JwtProperties jwtProperties;


    public UserAuthenticationHandler() {
    }

    public UserAuthenticationHandler(JwtProperties jwtProperties) {
        this.jwtProperties = jwtProperties;
    }

    /**
     * 对用户token 有效性验证
     * 在解析JWT字符串时,如果密钥不正确,将会解析失败,
     * 抛出SignatureException异常,说明该JWT字符串是伪造的
     * 在解析JWT字符串时,如果‘过期时间字段’已经早于当前时间,
     * 将会抛出ExpiredJwtException异常,说明本次请求已经失效
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, 
         HttpServletResponse response, Object handler) throws Exception {
        try {
            // 请求跨域验证放行 "OPTIONS"
            if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
                response.setStatus(HttpServletResponse.SC_OK);
                return true;
            }
            interceptThread.set(true);
            String token = request.getParameter(TOKEN);
            log.info("token: " + token);
            if (StringUtils.isEmpty(token)) {
                throw new OpenApiServiceException(OPEN_API_USER_LOGIN_TOKEN_ERROR);
            }
            UserInfo userInfo = JwtUtils.getInfoFromToken(token, 
                                jwtProperties.getPublicKey());
            if (userInfo != null) {
                tokenThread.set(userInfo);
                return true;
            } else {
                throw new OpenApiServiceException(OPEN_API_USER_LOGIN_TOKEN_ERROR);
            }
        } catch (Exception e) {
            throw new OpenApiServiceException(OPEN_API_USER_LOGIN_TOKEN_ERROR);
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, 
           HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
    }

    /**
     * token用户资源的释放
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, 
      HttpServletResponse response, Object handler,
       Exception ex) throws Exception {
       tokenThread.remove();
       interceptThread.remove();
    }


    public static UserInfo getUserInfo() {
        return tokenThread.get();
    }

    public static Boolean getInterceptBool() {
        return interceptThread.get() == null ? 
        false : interceptThread.get();
    }
}
/**
 * mvc入口处理类
 * @author zhoushisheng
 */
@Slf4j
@Configuration
@EnableConfigurationProperties(JwtProperties.class)
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private JwtProperties jwtProperties;

    private static List<String> paths = new ArrayList<>();
    static {
        paths.add("/swagger-ui.html/**");
        paths.add("/swagger-ui/**");
        paths.add("/swagger-resources/**");
        paths.add("/v2/api-docs/**");
        paths.add("/v3/api-docs/**");
        paths.add("/webjars/**");
        paths.add("/doc.html/**");
        paths.add("/favicon.ico");
        paths.add("/sync/**");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new UserAuthenticationHandler(jwtProperties))
                .addPathPatterns("/**")
                .excludePathPatterns(paths);

}

    /**
     * 处理跨域问题
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE","PATCH")
                .allowedHeaders("*")
                .maxAge(3600)
                .allowCredentials(true);
    }
}
/**
 * @author zhoushisheng
 * jwt的配置文件
 */
@Slf4j
@Data
@ConfigurationProperties(prefix = "aaa.xxx.ccc")
public class JwtProperties {

    /**
     * 加密的秘钥数据源
     */
    private String secret;


    /**
     * token过期时间单位为分钟
     */
    private int expire;


    /**
     * 公钥初始对象
     */
    private PublicKey publicKey;

    /**
     * 公钥字符常量值
     */
    private String publicKeyStr;


    /**
     * 私钥初始对象
     */
    private PrivateKey privateKey;

    /**
     * 私钥字符常量值
     */
    private String privateKeyStr;

    /**
     * 服务加载初始化秘钥对
     */
    @PostConstruct
    public void initData() {
        try {
            privateKey = RsaUtils.getPrivateKey(privateKeyStr);
            publicKey = RsaUtils.getPublicKey(publicKeyStr);
            log.info("=============RsaUtils...initData=============");
        } catch (Exception e) {
            log.error("RsaUtils initData error: " + e.getMessage(),e);
        }
    }
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值