使用JWT创建解析令牌及RSA非对称加密详解

 更新时间:2023年11月16日 08:29:03   作者:立小研先森  
这篇文章主要介绍了JWT创建解析令牌及RSA非对称加密详解,JWT是JSON Web Token的缩写,即JSON Web令牌,是一种自包含令牌,一种情况是webapi,类似之前的阿里云播放凭证的功能,另一种情况是多web服务器下实现无状态分布式身份验证,需要的朋友可以参考下

依赖

开源依赖pom引用地址

<dependency>
  <groupId>io.github.mingyang66</groupId>
  <artifactId>oceansky-jwt</artifactId>
  <version>4.3.2</version>
</dependency>

一、如何使用Java代码的方式生成RSA非对称秘钥

public class RsaPemCreatorFactory {
    /**
     * 公钥文件名
     */
    private static final String PUBLIC_KEY_FILE = "publicKey.pem";
    /**
     * 私钥文件名
     */
    private static final String PRIVATE_KEY_FILE = "privateKey.pem";
    private static final String publicKeyPrefix = "PUBLIC KEY";
    private static final String privateKeyPrefix = "PRIVATE KEY";
    /**
     * 算法
     */
    public static final String ALGORITHM = "RSA";
    public static void create(String directory) throws NoSuchAlgorithmException, IOException {
        // algorithm 指定算法为RSA
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        // 指定密钥长度为2048
        keyPairGenerator.initialize(1024);
        // 生成密钥
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        // 文件夹不存在,则先创建
        Files.createDirectories(Paths.get(directory));
        try (FileWriter writer = new FileWriter(String.join("", directory, PRIVATE_KEY_FILE));
             PemWriter pemWriter = new PemWriter(writer);
             FileWriter pubFileWriter = new FileWriter(String.join("", directory, PUBLIC_KEY_FILE));
             PemWriter pubPemWriter = new PemWriter(pubFileWriter)) {
            pemWriter.writeObject(new PemObject(privateKeyPrefix, keyPair.getPrivate().getEncoded()));
            pubPemWriter.writeObject(new PemObject(publicKeyPrefix, keyPair.getPublic().getEncoded()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

二、如何创建RSAPublicKey、RSAPrivateKey对象

public class RsaAlgorithmFactory {
    public static final String N = "\n";
    public static final String R = "\r";
    public static final String ALGORITHM = "RSA";

    /**
     * 获取公钥对象
     *
     * @param publicKey 公钥字符串
     * @return 公钥对象
     * @throws InvalidKeySpecException
     * @throws NoSuchAlgorithmException
     */
    public static RSAPublicKey getPublicKey(String publicKey) throws InvalidKeySpecException, NoSuchAlgorithmException {
        if (publicKey == null || publicKey.length() == 0) {
            throw new IllegalArgumentException("非法参数");
        }
        byte[] keyBytes = Base64.getDecoder().decode(publicKey.replace(N, "").replace(R, "").getBytes(StandardCharsets.UTF_8));
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
    }

    /**
     * 获取私钥对象
     *
     * @param privateKey 私钥字符串
     * @return 私钥对象
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] keyBytes = Base64.getDecoder().decode(privateKey.replace(N, "").replace(R, "").getBytes(StandardCharsets.UTF_8));
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
    }
}

三、如何创建解析JWT Token

创建工厂方法:

public class JwtFactory {
    /**
     * 创建JWT Token字符串
     *
     * @param builder   入参
     * @param algorithm 算法
     * @return token字符串
     */
    public static String createJwtToken(JWTCreator.Builder builder, Algorithm algorithm) {
        // header:typ、alg 算法
        return builder.sign(algorithm);
    }

    /**
     * JWT字符串解码后的对象
     *
     * @param jwtToken  令牌
     * @param algorithm 算法
     * @return 解析后的jwt token对象
     */
    public static DecodedJWT verifyJwtToken(String jwtToken, Algorithm algorithm) {
        JWTVerifier jwtVerifier = JWT.require(algorithm).build();
        return jwtVerifier.verify(jwtToken);
    }
}

实际使用案例:

    @Test
    public void test() throws InvalidKeySpecException, NoSuchAlgorithmException {
        RSAPublicKey publicKey = RsaAlgorithmFactory.getPublicKey(publicKey1);

        //Security.addProvider(new BouncyCastleProvider());
        RSAPrivateKey privateKey = RsaAlgorithmFactory.getPrivateKey(privateKey1);
        System.out.println(privateKey.getFormat());
        Map<String, Object> headers = new HashMap<>();
        headers.put("ip", "123.12.123.25.12");
        JWTCreator.Builder builder = JWT.create()
                //JWT唯一标识 jti
                .withJWTId(UUID.randomUUID().toString())
                .withHeader(headers)
                .withClaim("username", "田润叶")
                .withClaim("password", "不喜欢")
                //发布者 iss
                .withIssuer("顾养民")
                //发布时间 iat
                .withIssuedAt(Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()))
                //受众|收件人 aud
                .withAudience("田海民", "孙玉婷")
                //指定JWT在指定时间之前不得接受处理  nbf
                .withNotBefore(Date.from(LocalDateTime.now().plusMinutes(-1).atZone(ZoneId.systemDefault()).toInstant()))
                //JWT的主题 sub
                .withSubject("令牌")
                //JWT的密钥ID(实际未用到),用于指定签名验证的密钥 kid  com.auth0.jwt.algorithms.RSAAlgorithm.verify
                .withKeyId("sd")
                //JWT过期时间 exp
                .withExpiresAt(LocalDateTime.now().plusMinutes(5).atZone(ZoneId.systemDefault()).toInstant());
        String jwtToken = JwtFactory.createJwtToken(builder, Algorithm.RSA256(publicKey, privateKey));
        Assert.assertNotNull(jwtToken);

        DecodedJWT jwt = JwtFactory.verifyJwtToken(jwtToken, Algorithm.RSA256(publicKey, privateKey));
        Assert.assertEquals(jwt.getClaim("username").asString(), "田润叶");
        Assert.assertEquals(jwt.getClaim("password").asString(), "不喜欢");
        Assert.assertEquals(jwt.getHeaderClaim("ip").asString(), "123.12.123.25.12");
        Assert.assertEquals(jwt.getIssuer(), "顾养民");
        Assert.assertEquals(jwt.getAudience().get(0), "田海民");
        Assert.assertEquals(jwt.getAudience().get(1), "孙玉婷");
    }

到此这篇关于使用JWT创建解析令牌及RSA非对称加密详解的文章就介绍到这了,更多相关JWT创建解析令牌内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java 从互联网上爬邮箱代码示例

    Java 从互联网上爬邮箱代码示例

    这篇文章介绍了Java 从互联网上爬邮箱的有关内容,主要是一个代码示例,小编觉得挺不错的,这里给大家分享下,需要的朋友可以了解。
    2017-10-10
  • Java项目命名规范参考

    Java项目命名规范参考

    在实际项目开发中,命名规范的遵守可以提高代码的可读性和可维护性,本文就来介绍一下Java项目命名规范参考,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • Java线程Timer定时器用法详细总结

    Java线程Timer定时器用法详细总结

    在本篇文章里小编给大家整理的是关于Java线程Timer定时器用法详细总结内容,需要的朋友们学习下吧。
    2020-02-02
  • Jsoup获取全国地区数据属性值(省市县镇村)

    Jsoup获取全国地区数据属性值(省市县镇村)

    这篇文章主要介绍了Jsoup获取全国地区数据属性值(省市县镇村)的相关资料,需要的朋友可以参考下
    2015-10-10
  • 使用JWT创建解析令牌及RSA非对称加密详解

    使用JWT创建解析令牌及RSA非对称加密详解

    这篇文章主要介绍了JWT创建解析令牌及RSA非对称加密详解,JWT是JSON Web Token的缩写,即JSON Web令牌,是一种自包含令牌,一种情况是webapi,类似之前的阿里云播放凭证的功能,另一种情况是多web服务器下实现无状态分布式身份验证,需要的朋友可以参考下
    2023-11-11
  • Java连接各种数据库的方法

    Java连接各种数据库的方法

    这篇文章主要介绍了Java连接各种数据库的方法,实例分析了java连接MySQL、SQL Server、Sysbase、Oracle、PostgreSQL及DB2等数据库的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Java类和成员上的一些方法实例代码

    Java类和成员上的一些方法实例代码

    这篇文章主要介绍了Java类和成员上的一些方法实例代码,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • Java聊天室之实现接收和发送Socket

    Java聊天室之实现接收和发送Socket

    这篇文章主要为大家详细介绍了Java简易聊天室之实现接收和发送Socket功能,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以了解一下
    2022-10-10
  • Java用for循环Map详细解析

    Java用for循环Map详细解析

    本篇文章主要介绍了Java用for循环Map,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • SpringCloud openfeign声明式服务调用实现方法介绍

    SpringCloud openfeign声明式服务调用实现方法介绍

    在springcloud中,openfeign是取代了feign作为负载均衡组件的,feign最早是netflix提供的,他是一个轻量级的支持RESTful的http服务调用框架,内置了ribbon,而ribbon可以提供负载均衡机制,因此feign可以作为一个负载均衡的远程服务调用框架使用
    2022-12-12

最新评论