代码编织梦想


技术学习
专栏收录该内容
6 篇文章0 订阅
订阅专栏
引入
最近要开发一个谔码者管理平台,登录模块的技术选型我选择了JWT
Jwt可以保证放在客户端的登录信息不被篡改。
为了更加安全,加密算法我采用RSA非对称加密。即使用私钥生成Jwt,公钥校验Jwt。

问题
一开始想用spring的security框架,因为其中包含了JWT、Bcrypt以及其他内容,而且使用JwtHelper类,可以很方便的用私钥生成JWT,公钥解密。
但是搜遍全网,没找到JwtHelper设置Jwt过期时间的方法。
有个博主说,可以在载荷中手动增加iat、exp数据。但是经过测试,还是不行。
最终还是决定使用Jwts进行加密解密

JWT的加密解密
代码中提供Jwts和JwtHelper两种方式的加解密

第一步:生成密钥
通过keyTool(java提供的证书管理工具)生成
只要安装了JDK,就有这个工具。可以在cmd界面,输入keytool,检测是否有该工具。
若出现:

‘keytool’ 不是内部或外部命令,也不是可运行的程序或批处理文件。


可以进入jdk安装目录,bin文件夹下,就有keytool.exe文件。
此时,在地址栏输入cmd,回车,即可在此处打开cmd窗口。

执行以下命令:

// 以下指令为一行,设置多行是方便阅读
keytool -genkeypair 
-alias 密钥别名 
-keyalg 使用的算法 
-keypass 密钥的访问密码 
-keystore 生成的密钥库文件名,扩展名是jks
-storepass 密钥库的访问密码,用来打开jks文件
1
2
3
4
5
6
7

输入信息后,即可在当前目录生成jks文件。

第二步:导出公钥
对于微服务来说,私钥放在认证服务上,其他服务只需要存公钥即可。因为其他服务只做校验,不加密JWT
可以通过openssl导出密钥,即字符串格式的公钥或私钥
openssl需要安装,点击此处跳转下载
安装好之后,增加环境变量:

执行以下命令即可:

keytool -list -rfc --keystore jks文件(包含扩展名.jks) | openssl x509 -inform pem -pubkey
1

将 -----BEGIN PUBLIC KEY----- 与 -----END PUBLIC KEY----- 中的内容复制,新建文件并存放。
一般是创建public.key

将其放入项目的resource目录下,即可


第三步:加密JWT
    /**
     * 根据私钥生成JWT令牌
     *
     * @author Eugenema
     * @date 2022/2/19 17:49
     *
     * @param userInfo 用户信息
     *
     * @return 加密后的JWT
     **/
    public String createJWT(UserInfo userInfo){
        //载荷
        Map<String,Object> payload = new HashMap<>(2);
        payload.put("id", userInfo.getId());
        payload.put("userName",userInfo.getName());

        /** 私钥:resource目录下 */
        ClassPathResource keyFileResource = new ClassPathResource("emPerson.jks");
        //创建秘钥工厂,参数为:秘钥文件、秘钥库密码
        //import org.springframework.security.rsa.crypto.KeyStoreKeyFactory;
        //pom文件:
        /**
        <dependency>
              <groupId>org.springframework.security</groupId>
              <artifactId>spring-security-rsa</artifactId>
              <version>1.0.11.RELEASE</version>
        </dependency>
        */
        KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(keyFileResource, "密钥库密码password".toCharArray());
        //获取秘钥,参数为:别名,秘钥密码
        KeyPair keyContent = keyStoreKeyFactory.getKeyPair("alias别名", "秘钥的密码".toCharArray());
        /** 私钥 */
        PrivateKey privateKey = keyContent.getPrivate();

        //通过JwtHelper生成JWT
        //由于无法设置过期时间,被弃用
//        Jwt jwtContent = JwtHelper.encode(JSON.toJSONString(payload), new RsaSigner(privateKey));
//        String jwtEncoded = jwtContent.getEncoded();
//        System.out.println(jwtEncoded);

        //通过Jwts生成JWT
        //pom文件:
        /**
        <dependency>
              <groupId>io.jsonwebtoken</groupId>
              <artifactId>jjwt</artifactId>
              <version>0.9.0</version>
        </dependency>
        */
        JwtBuilder eugeneMa = Jwts.builder()
                //设置载荷
                .addClaims(payload)
                //设置ID,据说能防止重放攻击
                .setId(String.valueOf(System.currentTimeMillis()))
                //设置主题
                .setSubject("eugeneMa")
                //设置签发时间
                .setIssuedAt(new Date())
                //设置过期时间
                .setExpiration(new Date(System.currentTimeMillis() + 30000))
                //设置加密算法及私钥
                .signWith(SignatureAlgorithm.RS256, privateKey);
        //返回JWT
        return eugeneMa.compact();
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
第四步:解密JWT
    /**
     * 解析JWT
     *
     * @author Eugenema
     * @date 2022/2/19 18:47
     *
     * @param jwt 要解密的JWT
     *
     * @return 解析后的jwt
     **/
    public String parseJwt(String jwt){
        //通过JwtHelper解析
        //Jwt token = JwtHelper.decodeAndVerify(jwt, new RsaVerifier(getPubKey));
        //return token.getClaims();
        
        //通过Jwts解析
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(getPubKey()).parseClaimsJws(jwt);
        return claimJws.getBody();
    }

    /**
     * 获取公钥
     *
     * @author Eugenema
     * @date 2022/2/19 19:01
     *
     * @return 公钥,若获取失败则返回null
     **/
    private static PublicKey getPubKey() {
        //指向resource目录下的公钥文件
        Resource publicKey = new ClassPathResource("public.key");
        try {
            InputStreamReader publicKeyIs = new InputStreamReader(publicKey.getInputStream());
            BufferedReader publicKeyBr = new BufferedReader(publicKeyIs);
            StringBuilder publicKeySb = new StringBuilder();
            String line;
            //将文件中的多行变为一行
            while ((line = publicKeyBr.readLine()) != null) {
                publicKeySb.append(line);
            }
            
            //将String转换成java的PublicKey对象
            byte[] byteKey = Base64.getDecoder().decode(publicKeySb.toString());
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(byteKey);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePublic(x509EncodedKeySpec);
        } catch (Exception e) {
            logger.error("获取公钥异常!", e);
            return null;
        }
    }
————————————————
版权声明:本文为CSDN博主「谔码者」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_37470815/article/details/123027798

springboot使用springsecurity搭建基于非对称加密的jwt及前后端分离的搭建_lhc0512的博客-爱代码爱编程

安全问题是一个比较复杂的问题,之前使用过Shiro这个安全框架,确实挺简单的,后来使用SpringSecurity,SpringSecurity更细粒度可控,现在做项目基本都使用前后端分离的,很少再使用Thymeleaf这类

Java校园淘项目实战(1)————JWT+RSA非对称加密生成token-爱代码爱编程

springCloud环境配置好了,接下来就是先把工具类写好,因为接下来要写用户接口微服务,所有打算先把密钥工具类和生成token的工具类写好。 (1)yml配置,里面声明了公钥和私钥存放的地方。 server: port: 10021 spring: application: name: commons-service eureka:

Spring Security 在 Spring Boot 中集成 JWT + RSA【分布式】-爱代码爱编程

1.1 简介 1.1.1 分布式认证   分布式认证即用户只需要登录一次就可以访问所有互相信任的子系统。在每台服务中都有一个 session 但是各个 session 之间时无法共享资源的,所以 session 不能作为单点登录的解决方案。单点登录一般分为两个部分:  ♞ 用户认证:这一环节主要是用户向认证服务发起认证请求,认证服务给用户返回一个成功的

gateway oauth2 对称加密_Spring Security OAuth2 实现 使用JWT-不想当码农的程序员-爱代码爱编程

回过头来说一下 资源 服务 器的问题点吧,这里OAuth2+JWT用的是 spring security ,具体怎么用 spring security 搭建 资源 服务 器我就不说了。这里要讨论的问题是这样的,我们希望在 spring mvc中,直接通过如下的形式获得登录用户信息@GetMapping("/me") public Au

SpringBoot+SpringSecurity+JWT整合实现单点登录SSO史上最全详解-爱代码爱编程

作者:波波烤鸭 blog.csdn.net/qq_38526573/article/details/103409430 一、什么是单点登陆 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统 二

SpringBoot+SpringSecurity+JWT实现认证和授权-爱代码爱编程

SprinBoot 系列文章: Spring Boot入门之Hello Spring BootSpringBoot 配置多个JdbcTemplateSpringBoot 整合MybatisCAS统一登录认证(3): CAS 客户端接入实践SpringBoot 整合Mail实现邮件发送数据库连接池优化配置(druid,dbcp,c3p0)SpringBoo

SpringBoot(七):JWT与Rsa非对称加密-爱代码爱编程

文章目录 什么是JWT?什么是Rsa非对称加密?Java 实现引入依赖application.yml配置文件JwtPropertiesRsaPropertiesRsaUtils 工具类JwtUtils 工具类最后 什么是JWT? Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((R

SpringSecurity + JWT 实现单点登录-爱代码爱编程

本文我们来看下 SpringSecurity  + JWT 实现单点登录操作,本文 2W 字,预计阅读时间 30 min,文章提供了代码骨架,建议收藏。 一、什么是单点登陆 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任

Spring集成Jwt操作-爱代码爱编程

流程:用户登录(用户名&密码)->  后端方法验证(一般后端会有"安全"框架,开放一个白名单路径:/login)->  验证通过生成Token返给前端->  前端通过Cookie保存token之后请求在请求头中携带Token->  后端验证Token没啥问题放行(一般都会配置拦截器或者啥的 验证通过就让你走,没有Token一

SpringSecurity+JWT框架项目前后端分离(实战)-爱代码爱编程

SpringSecurity 一:简介 1.Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro,它提供了更丰富的功能,社区资源也比Shiro丰富。一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的比较

SpringSecurity+jwt安全框架-爱代码爱编程

目录 1、环境搭建 1.1maven项目 1.2导入依赖 2.测试环境 3.实现安全认证 3.1原理  3.1.1实现UserDetailsService接口默认是从内存中获取密码,我们需要从数据库中来比对用户信息 3.2返回自定义结果集 3.3自定义实现类实现UserDetailsService接口  5.jwt的使用 5.1权限的

springsecurity系列——jwt(jjwt)day1-2_简明编程的博客-爱代码爱编程

SpringSecurity系列——JWTday1-2 简介官网地址Session对比JWTsession问题JWTJWT的优点JWT的结构HeaderPayloadSignatureJJWT地址JJWT基础使用和介绍导入依赖quickstart代码解释设置使用加密算法构建jwt设置payload中包含的用户信息设置加密算法压缩生成token令牌错

springboot 开发 web flux_tonysong111073的博客-爱代码爱编程

一、什么是响应式编程   1.1 什么是WebFlux         WebFlux是从Spring Framework5.0以后开始引入的响应式web编程框架。与传统的Spring mvc不同WebFlux不需要Servlet API,在完全异步且无阻塞的通过Reactor项目实现Reactive Streams 规范。        WebFl

微服务网关鉴权:gateway使用、网关限流使用、用户密码加密、jwt鉴权-爱代码爱编程

点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏  原创 | Java 2021 超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析