Java jwt使用公钥字符串验证解析token锁方法详解

下面是详细讲解“Java jwt使用公钥字符串验证解析token锁方法详解”的完整攻略。

一、什么是JWT

JWT是一种开放的标准(RFC 7519),定义了一种简洁的、自包含的方式用于在各方之间传递信息。该信息可以被验证和信任,因为它是经过数字签名的。JWT可以使用对称加密和非对称加密两种方式进行签名,其中非对称加密使用公钥和私钥进行加密和解密。

JWT包含三个部分:头部、载荷和签名,如下所示:

// 头部
{
  "alg": "HS256",
  "typ": "JWT"
}

// 载荷
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

// 签名
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

其中,头部用于描述JWT的元数据信息,如签名算法(alg)和令牌类型(typ)等。载荷包含实际的用户数据,如用户ID、用户名、过期时间等。签名则用于保证JWT的完整性和真实性,通过对头部、载荷和密钥进行签名,得到签名数据,可以用于校验JWT是否被篡改。

二、使用公钥字符串验证解析JWT

对于使用公钥字符串验证解析JWT的场景,我们需要在服务器上设置一组公钥和私钥,使用私钥对JWT进行签名,然后将JWT和公钥字符串返回给客户端。

客户端收到JWT后,在需要验证和解析JWT的地方,可以将公钥字符串转换成公钥,使用公钥对JWT进行验证和解析。

下面是一些基本的示例代码。

1. 生成JWT

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtUtils {

    private static final String ALGORITHM = "RSA";
    private static final int KEY_SIZE = 2048;
    private static final String PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n" +
            "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDR4d/SLGU8W/cO\n" +
            "kVXIGPmL+UDzpzB9BFq+vP1dUxX+l5G0kvBdzz19oIZlp1Vsmn8c/g/ap7hTfX0Z\n" +
            //省略私钥部分
            "-----END PRIVATE KEY-----";
    private static final String PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n" +
            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0eHf0ixlPFv3DpFVyBj5\n" +
            "i/lA86cwfQRavrz9XVMV/peRtJLwXc89faCGZadVbJp/HP4P2qe4U319GQ6N6Zg5\n" +
            //省略公钥部分
            "-----END PUBLIC KEY-----";

    public static String createToken(String userId) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("sub", userId);
        claims.put("iat", Date.from(Instant.now()));
        claims.put("exp", Date.from(Instant.now().plus(1, ChronoUnit.DAYS)));
        KeyPair keyPair = generateKeyPair();
        String privateKeyString = getPrivateKeyString(keyPair);
        return Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.RS256, keyPair.getPrivate())
                .compact();
    }

    private static KeyPair generateKeyPair() {
        KeyPairGenerator keyPairGenerator;
        try {
            keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
            keyPairGenerator.initialize(KEY_SIZE);
            return keyPairGenerator.generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    private static String getPrivateKeyString(KeyPair keyPair) {
        return "-----BEGIN PRIVATE KEY-----\n" +
                Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()) +
                "\n-----END PRIVATE KEY-----";
    }

}

此处我们使用RSA算法生成了一对公钥和私钥,并使用私钥对JWT进行签名并生成一个token。其中,私钥和公钥的字符格式是PEM格式的,需要进行解析和转换。

2. 验证和解析JWT

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;

import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class JwtUtils {

    // ...

    public static boolean verifyToken(String token) {
        try {
            PublicKey publicKey = getPublicKey();
            Jws<Claims> claimsJws = Jwts.parserBuilder()
                    .setSigningKey(publicKey)
                    .build()
                    .parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static Claims parseToken(String token) {
        PublicKey publicKey = getPublicKey();
        return Jwts.parserBuilder()
                .setSigningKey(publicKey)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    private static PublicKey getPublicKey() throws Exception {
        String publicKeyString = PUBLIC_KEY
                .replace("-----BEGIN PUBLIC KEY-----", "")
                .replace("-----END PUBLIC KEY-----", "")
                .replaceAll("\\s","");
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

}

此处我们提供了两个方法,一个是验证token是否有效,一个是解析token中的数据(也就是头部和载荷)。在两个方法中,都使用了公钥对JWT进行验证和解析。

三、示例说明

下面是两个示例说明,分别演示了如何生成JWT和验证JWT的过程。

示例一:生成JWT

public static void main(String[] args) {
    String token = JwtUtils.createToken("123456");
    System.out.println(token);
}

运行结果:

eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIxMjM0NTYiLCJpYXQiOjE2MjczNzc5MDcsImV4cCI6MTYyNzQ2NDA5N30.XB6WvHoltDH-5jwSBfLqM4-hnltwIz2LaklZVBZcDwzACVKKyw-aU2XxwkVGllCgjzDtl8JGtO0cc_Kh0xo3WMoovqW1uwYGW-p6pN1n8mU8tgyn2ob1nZyDK0VQU0_CXjHPScjRljwoeZoY1b24-ctKzZiS9rwver_3BIQf1-nCJ9g3trNvUfkc9vZeZKakHSMtr9v6JizlOp2R0-kwmM3whiiIH_QjAbYcqOyU_Vbgi7Q4y91umx4DXZS9O9vDuQ15rvvPvVOXdbEBhep83mRrvvFIwzmYLnEp5a5cyQKw6R7fWYBHHbDOhK3OqDKtEYDHb3pNtf7-Vw

生成的jwt包含了头部、载荷和签名信息,其中载荷中包含了sub、iat和exp等字段信息。这里我们使用了PEM格式的字符串描述了私钥和公钥,通过使用私钥对JWT进行签名和验证,提高了数据的安全性。

示例二:解析JWT

public static void main(String[] args) {
    String token = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIxMjM0NTYiLCJpYXQiOjE2MjczNzc5MDcsImV4cCI6MTYyNzQ2NDA5N30.XB6WvHoltDH-5jwSBfLqM4-hnltwIz2LaklZVBZcDwzACVKKyw-aU2XxwkVGllCgjzDtl8JGtO0cc_Kh0xo3WMoovqW1uwYGW-p6pN1n8mU8tgyn2ob1nZyDK0VQU0_CXjHPScjRljwoeZoY1b24-ctKzZiS9rwver_3BIQf1-nCJ9g3trNvUfkc9vZeZKakHSMtr9v6JizlOp2R0-kwmM3whiiIH_QjAbYcqOyU_Vbgi7Q4y91umx4DXZS9O9vDuQ15rvvPvVOXdbEBhep83mRrvvFIwzmYLnEp5a5cyQKw6R7fWYBHHbDOhK3OqDKtEYDHb3pNtf7-Vw";
    Claims claims = JwtUtils.parseToken(token);
    System.out.println(claims);
}

运行结果:

{sub=123456, iat=1627377907, exp=1627464097}

解析JWT后,我们得到了payload中携带的用户数据,包括sub、iat和exp字段,分别代表用户ID、JWT的签发时间和过期时间。这些数据可以根据业务需要进行进一步的处理。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java jwt使用公钥字符串验证解析token锁方法详解 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • 基于Java中的StringTokenizer类详解(推荐)

    下面是关于“基于Java中的StringTokenizer类详解”的完整攻略。 1. 什么是StringTokenizer类? StringTokenizer类是Java中用来分割字符串的类,它的作用类似于split()方法。使用StringTokenizer类可以将一个字符串按照指定的分隔符进行分割,得到一个包含多个子字符串的字符串数组。 2. Strin…

    Java 2023年5月27日
    00
  • 解析SpringBoot项目开发之Gzip压缩过程

    下面详细解析SpringBoot项目开发中的Gzip压缩过程: 1. 什么是Gzip压缩 Gzip是一种文件压缩格式,用于减小文件大小,节省传输带宽,提高响应速度。在Web应用中,客户端可以通过发起支持Gzip压缩的请求,服务器返回经过Gzip压缩的响应,从而实现数据传输的优化。 2. SpringBoot中开启Gzip压缩 在SpringBoot中,可以通…

    Java 2023年5月19日
    00
  • JavaWeb读取配置文件的四种方法

    关于JavaWeb读取配置文件的四种方法,我将会按照以下四种方法作详细介绍: 使用ClassLoader的getResourceAsStream方法读取 使用Properties类读取 使用ServletContext的getRealPath方法读取 使用Spring框架的PropertiesLoaderUtils方法读取 1. 使用ClassLoader的…

    Java 2023年5月19日
    00
  • 基于Spring Security前后端分离的权限控制系统问题

    基于Spring Security前后端分离的权限控制系统是一个非常常见的开发需求。下面将提供完整攻略,从搭建环境、配置安全策略、实现权限控制等方面讲解该系统的具体实现。其中示例将分别展示两种不同的权限控制方式。 1. 搭建环境 首先,需要搭建一个Spring Boot项目,并且集成Spring Security。需要在项目中引入以下依赖: <depe…

    Java 2023年5月20日
    00
  • Spring JDBC 框架简介

    Spring JDBC框架简介 Spring是目前最流行的Java应用程序框架之一,在众多的Spring模块中,Spring JDBC是其中之一。本文将为你详细讲解Spring JDBC框架的概念、特点和使用方法,同时提供两个实例说明。 1. Spring JDBC框架概述 Spring JDBC框架是用轻量级的Java框架Spring来简化Java应用程序…

    Java 2023年6月2日
    00
  • struts2中常用constant命令配置方法

    在Struts2中,可以通过配置constant命令来设置全局常量,方便在整个应用程序中共用这些常量。以下是配置constant命令的方法及示例: 配置常量 在struts.xml中使用constant命令可以配置全局常量: <constant name="CONSTANT_NAME" value="CONSTANT_VA…

    Java 2023年5月20日
    00
  • Struts2实现CRUD(增 删 改 查)功能实例代码

    实现CRUD(增删改查)功能是Web开发中最基本的功能之一,本文将详细讲解如何使用Struts2框架实现该功能。 步骤一:新建项目并引入依赖 首先,在Eclipse中新建一个动态Web项目,命名为:Struts2CRUD。接着,新增一个名为“lib”的文件夹,用于存放所需的Jar包。然后,将以下Jar包复制到该文件夹中: commons-lang3-x.x.…

    Java 2023年5月20日
    00
  • 详解Mysql如何实现数据同步到Elasticsearch

    如何实现MySQL数据同步到Elasticsearch?本文将为大家提供一种常见的实现方法,即使用Logstash工具来实现同步。具体步骤如下: 步骤一:安装Logstash 首先,我们需要安装Logstash,它是一个开源的数据处理工具,可以将各种形式的数据发送到Elasticsearch。可以通过以下方式安装: wget https://artifact…

    Java 2023年6月16日
    00
合作推广
合作推广
分享本页
返回顶部