使用JWT創(chuàng)建解析令牌及RSA非對稱加密詳解
依賴
開源依賴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();
// 文件夾不存在,則先創(chuàng)建
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();
}
}
}二、如何創(chuàng)建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("非法參數(shù)");
}
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);
}
}
三、如何創(chuàng)建解析JWT Token
創(chuàng)建工廠方法:
public class JwtFactory {
/**
* 創(chuàng)建JWT Token字符串
*
* @param builder 入?yún)?
* @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);
}
}
實(shí)際使用案例:
@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唯一標(biāo)識 jti
.withJWTId(UUID.randomUUID().toString())
.withHeader(headers)
.withClaim("username", "田潤葉")
.withClaim("password", "不喜歡")
//發(fā)布者 iss
.withIssuer("顧養(yǎng)民")
//發(fā)布時間 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(實(shí)際未用到),用于指定簽名驗(yàn)證的密鑰 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(), "顧養(yǎng)民");
Assert.assertEquals(jwt.getAudience().get(0), "田海民");
Assert.assertEquals(jwt.getAudience().get(1), "孫玉婷");
}
到此這篇關(guān)于使用JWT創(chuàng)建解析令牌及RSA非對稱加密詳解的文章就介紹到這了,更多相關(guān)JWT創(chuàng)建解析令牌內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 微信小程序使用uni-app和springboot實(shí)現(xiàn)一鍵登錄功能(JWT鑒權(quán))
- SpringSecurity整合JWT的使用示例
- SpringBoot整合SpringSecurity和JWT和Redis實(shí)現(xiàn)統(tǒng)一鑒權(quán)認(rèn)證
- jwt生成token和token解析基礎(chǔ)詳解
- Golang RSA生成密鑰、加密、解密、簽名與驗(yàn)簽的實(shí)現(xiàn)
- JavaWeb實(shí)現(xiàn)RSA+AES混合加密
- Nuxt引用cookie-universal-nuxt在服務(wù)端請求cookie方式
- vue使用jsencrypt實(shí)現(xiàn)rsa前端加密的操作代碼
相關(guān)文章
Spring Cloud入門教程之Zuul實(shí)現(xiàn)API網(wǎng)關(guān)與請求過濾
這篇文章主要給大家介紹了關(guān)于Spring Cloud入門教程之Zuul實(shí)現(xiàn)API網(wǎng)關(guān)與請求過濾的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-05-05
分析java中全面的單例模式多種實(shí)現(xiàn)方式
單例模式是一種常用的軟件設(shè)計(jì)模式,單例對象的類只能允許一個實(shí)例存在。許多時候整個系統(tǒng)只需要擁有一個的全局對象,有利于協(xié)調(diào)系統(tǒng)整體的行為。比如在某個服務(wù)器程序中,該服務(wù)器的配置信息存放在一個文件中。本文將介紹它的思想和多種實(shí)現(xiàn)方式2021-06-06
SpringCloud通過Feign傳遞List類型參數(shù)方式
這篇文章主要介紹了SpringCloud通過Feign傳遞List類型參數(shù)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
SpringBoot整合SpringBoot-Admin實(shí)現(xiàn)監(jiān)控應(yīng)用功能
本文主要介紹如何整合Spring Boot Admin,以此監(jiān)控Springboot應(yīng)用,文中有相關(guān)的示例代碼供大家參考,需要的朋友可以參考下2023-05-05
Java swing實(shí)現(xiàn)音樂播放器桌面歌詞字體變色效果
這篇文章主要為大家詳細(xì)介紹了Java swing實(shí)現(xiàn)音樂播放器桌面歌詞字體變色效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06
利用Java實(shí)現(xiàn)在PDF中添加工具提示
這篇文章主要介紹了如何通過Java在PDF中添加工具提示,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定的參考價(jià)值,感興趣的可以學(xué)習(xí)一下2022-01-01

