首页 > 编程语言 >java生成jwt并使用RSA签名

java生成jwt并使用RSA签名

时间:2023-01-05 00:56:07浏览次数:40  
标签:公钥 java jwt RSAKey 生成 new RSA

一、生成jwt

在java中生成jwt的库用得比较多的是nimbus-jose-jwt、jose4j、java-jwt 和 jjwt (已迁移为jwt-api)。这里使用nimbus-jose-jwt。

引入依赖:

implementation("com.nimbusds:nimbus-jose-jwt:9.27")

生成jwt:

// (1) 生成RSA公钥-秘钥对
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// (2) Create RSA signer
JWSSigner signer = new RSASSASigner(keyPair.getPrivate());

// (3) 生成jws头
JWSHeader jwsHeader = new JWSHeader
  .Builder(JWSAlgorithm.RS512)    // 指定 RSA 算法
  .type(JOSEObjectType.JWT)
  .build();

// (4) 生成jws对象
JWSObject jwsObject = new JWSObject(new JWSHeader(JWSAlgorithm.RS512), new Payload(Map.of("userId", "123456")));
// (5) 给jwt签名
jwsObject.sign(signer);
// (6) 生成jwt字符串
String jwtToken = jwsObject.serialize();

(1)生成RSA公钥-秘钥对。

(2)使用RSA秘钥对创建一个jws签名对象。

(3)生成jws头,并指定签名算法JWSAlgorithm.RS512。

(4)生成jws对象,claims数据为Map.of("userId", "123456")。

(5)使用jws对象给jwt签名。

(6)生成jwt字符串。

二、解析jwt token

JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) keyPair.getPublic());(1)
JWSObject parseObj = JWSObject.parse(jwtToken);(2)
if(parseObj.verify(verifier)) {(3)
  Map<String, Object> stringObjectMap = parseObj.getPayload().toJSONObject();
  System.err.println(stringObjectMap);
}

(1)使用RSA公钥(前面步骤中生成的密钥对)创建一个验证器。

(2)解析jwt token。

(3)验证jwt签名,如果验证通过则jwt是有效的。

三、从证书生成RSA对象

1. 使用java自带的keytool工具生成证书文件
$ keytool -genkey -alias jwt-alias-name -keyalg RSA -keystore jwt.jks
2. 生成jwt
//(1) 从本地证书读取秘钥对
char[] password  = "123456".toCharArray();
FileInputStream fis = new FileInputStream("/home/jwt.jks");
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(fis, password);
Key key = keyStore.getKey("jwt-alias-name", password);
KeyPair pair = null;
if (key instanceof PrivateKey) {
  Certificate certificate = keyStore.getCertificate("jwt-alias-name");
  PublicKey publicKey = certificate.getPublicKey();
  pair = new KeyPair(publicKey, (PrivateKey)key);
}

// (2)创建RSAKey对象
RSAKey rsaKey = new RSAKey.Builder((RSAPublicKey) pair.getPublic())
  .privateKey(pair.getPrivate())
  .keyID(UUID.randomUUID().toString())
  .build();
// (3) 使用RSAKey生成JWSSigner
JWSSigner jwsSigner = new RSASSASigner(rsaKey, true);   // rsaKey 生成签名器
// 生成jwt token......

(1)从本地证书读取秘钥对。

(2)创建RSAKey对象。

(3)使用RSAKey生成JWSSigner,后续操作和之前一致。

5. 解析jwt token
String token = ...;
JWSObject jwsObject = JWSObject.parse(token);

// (1)使用签名步骤生成的RSA
RSAKey rsaKey = ...;
RSAKey publicRsaKey = rsaKey.toPublicJWK();
// (2) 使用公钥创建JWSVerifier
JWSVerifier jwsVerifier = new RSASSAVerifier(publicRsaKey);

// (3)验证签名
if (!jwsObject.verify(jwsVerifier)) {
    throw new RuntimeException("token签名不合法!");
}
Map<String, Object> claims = jwsObject.getPayload().toJSONObject();

(1)使用签名步骤生成的RSA。

(2)使用公钥创建JWSVerifier。

(3)验证签名。

四、生成jwks

// (1) 生成RSA公钥-秘钥对
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();

RSAKey rsaKey = new RSAKey.Builder((RSAPublicKey) keyPair.getPublic())
  .privateKey(keyPair.getPrivate())
  .keyID(UUID.randomUUID().toString())
  .build();
// (1)显示秘钥和公钥
System.out.println(rsaKey);
// (2)只显示公钥
System.out.println(rsaKey.toPublicJWK());

(1)显示秘钥和公钥。

(2)只显示公钥。

jwt标准格式:

// Convert to JWK format
JWK jwk = new RSAKey.Builder((RSAPublicKey)keyPair.getPublic())
  .privateKey((RSAPrivateKey)keyPair.getPrivate())
  .keyUse(KeyUse.SIGNATURE)
  .keyID(UUID.randomUUID().toString())
  .issueTime(new Date())
  .build();
// (1)显示秘钥和公钥
System.out.println(jwk);
// (2)只显示公钥
System.out.println(jwk.toPublicJWK());

(1)显示秘钥和公钥。

(2)只显示公钥。

五、从jwks生成RSAKey

RSAKey rsaKey1 = RSAKey.parse("{...}");
JWSVerifier verifier = new RSASSAVerifier(rsaKey1);

JWSObject parseObj = JWSObject.parse(jwtToken);
if(parseObj.verify(verifier)) {
  Map<String, Object> stringObjectMap = parseObj.getPayload().toJSONObject();
  System.err.println(stringObjectMap);
}

五、参考地址

[Examples](

标签:公钥,java,jwt,RSAKey,生成,new,RSA
From: https://www.cnblogs.com/yourblog/p/17026420.html

相关文章

  • Open Source Customer Support Chat System Implementation Of Pop-up Effect JavaScr
    WhenIwasimplementingtheonlinecustomersupportchatsystem'spopupeffectJavaScriptSDK,theSDKcodethatwaspubliclyexposedwasintheformofaself......
  • JavaScript 自执行函数防止冲突全局作用域变量 - 在线客服源码实现弹窗效果JavaScript
    当我在实现在线客服源码弹窗效果JavaScriptSDK时,对外公开的SDK代码就是使用的自执行函数的形式。使用自执行函数来实现JavaScriptSDK有以下好处:封装代码:自执行函数......
  • 网站中引入了多个版本的 JavaScript 库防止对象冲突的方法 - 在线客服系统源码
    如果你在网站中引入了多个版本的JavaScript库,并且在你的JavaScript中使用了同名的对象,则可能会出现对象名称冲突的情况。使用命名空间来解决这个问题。例如,你可以在你......
  • 6.JavaScript HTML DOM和事件
    实验名称JavaScriptHTMLDOM和事件实验目的1.了解DOMHTML的概念和用法2.掌握DOM事件的用法实验原理HTMLDOM(文档对象模型)当网页被加载时,浏览器会创建页面的文档......
  • 5.JavaScript基础语法
    实验原理概念:JavaScript是世界上最流行的、轻量级的、脚本编程语言,可插入HTML页面,由浏览器执行。将这种脚本语言引入html,有三种方式:<script>与<script>标签,可被放置在HT......
  • Java相关问答
    简述Java中final关键字的三种用法。(1)final在类之前,表示该类是最终类,表示该类不能再被继承。(2)final在方法之前,表示该类方法是最终方法,该方法不能被任何派生的子类覆盖。......
  • hmac php java结果不一样问题
    比如我们有个服务是PHP提供的,要求的签名方式hmacSha256取摘要,然后Base64编码转化成可见字符。PHP那边的源码是这样的$result=base64_encode(hash_hmac("SHA256"......
  • hmacSha256 php java结果不一样问题
    比如我们有个服务是PHP提供的,要求的签名方式hmacSha256取摘要,然后Base64编码转化成可见字符。PHP那边的源码是这样的$result=base64_encode(hash_hmac("SHA256"......
  • Java8新特性-Lambda表达式
    Lambda表达式在Java语言中引入了一个操作符**“->”**,该操作符被称为Lambda操作符或箭头操作符。它将Lambda分为两个部分:左侧:指定了Lambda表达式需要的所有参数......
  • SpringBoot+springSecurity+jwt入门案例
    SpringSecurity+JWT整合1.简介SpringSecurity是spring的一个安全管理框架,相比另一个安全框架shiro,它提供了更丰富的功能,社区资源也比shiro丰富。web应用主要用于认证和......