使用JWT創(chuàng)建解析令牌及RSA非對(duì)稱加密詳解
依賴
開源依賴pom引用地址
<dependency> <groupId>io.github.mingyang66</groupId> <artifactId>oceansky-jwt</artifactId> <version>4.3.2</version> </dependency>
一、如何使用Java代碼的方式生成RSA非對(duì)稱秘鑰
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); // 指定密鑰長(zhǎng)度為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對(duì)象
public class RsaAlgorithmFactory { public static final String N = "\n"; public static final String R = "\r"; public static final String ALGORITHM = "RSA"; /** * 獲取公鑰對(duì)象 * * @param publicKey 公鑰字符串 * @return 公鑰對(duì)象 * @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); } /** * 獲取私鑰對(duì)象 * * @param privateKey 私鑰字符串 * @return 私鑰對(duì)象 * @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字符串解碼后的對(duì)象 * * @param jwtToken 令牌 * @param algorithm 算法 * @return 解析后的jwt token對(duì)象 */ 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)識(shí) jti .withJWTId(UUID.randomUUID().toString()) .withHeader(headers) .withClaim("username", "田潤(rùn)葉") .withClaim("password", "不喜歡") //發(fā)布者 iss .withIssuer("顧養(yǎng)民") //發(fā)布時(shí)間 iat .withIssuedAt(Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant())) //受眾|收件人 aud .withAudience("田海民", "孫玉婷") //指定JWT在指定時(shí)間之前不得接受處理 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過(guò)期時(shí)間 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(), "田潤(rùn)葉"); 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非對(duì)稱加密詳解的文章就介紹到這了,更多相關(guān)JWT創(chuàng)建解析令牌內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(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ù)端請(qǐng)求cookie方式
- vue使用jsencrypt實(shí)現(xiàn)rsa前端加密的操作代碼
相關(guān)文章
Spring Cloud入門教程之Zuul實(shí)現(xiàn)API網(wǎng)關(guān)與請(qǐng)求過(guò)濾
這篇文章主要給大家介紹了關(guān)于Spring Cloud入門教程之Zuul實(shí)現(xiàn)API網(wǎng)關(guān)與請(qǐng)求過(guò)濾的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-05-05分析java中全面的單例模式多種實(shí)現(xiàn)方式
單例模式是一種常用的軟件設(shè)計(jì)模式,單例對(duì)象的類只能允許一個(gè)實(shí)例存在。許多時(shí)候整個(gè)系統(tǒng)只需要擁有一個(gè)的全局對(duì)象,有利于協(xié)調(diào)系統(tǒng)整體的行為。比如在某個(gè)服務(wù)器程序中,該服務(wù)器的配置信息存放在一個(gè)文件中。本文將介紹它的思想和多種實(shí)現(xiàn)方式2021-06-06spring?jpa設(shè)置多個(gè)主鍵遇到的小坑及解決
這篇文章主要介紹了spring?jpa設(shè)置多個(gè)主鍵遇到的小坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06SpringCloud通過(guò)Feign傳遞List類型參數(shù)方式
這篇文章主要介紹了SpringCloud通過(guò)Feign傳遞List類型參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03SpringBoot整合SpringBoot-Admin實(shí)現(xiàn)監(jiān)控應(yīng)用功能
本文主要介紹如何整合Spring Boot Admin,以此監(jiān)控Springboot應(yīng)用,文中有相關(guān)的示例代碼供大家參考,需要的朋友可以參考下2023-05-05Java swing實(shí)現(xiàn)音樂(lè)播放器桌面歌詞字體變色效果
這篇文章主要為大家詳細(xì)介紹了Java swing實(shí)現(xiàn)音樂(lè)播放器桌面歌詞字體變色效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06利用Java實(shí)現(xiàn)在PDF中添加工具提示
這篇文章主要介紹了如何通過(guò)Java在PDF中添加工具提示,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定的參考價(jià)值,感興趣的可以學(xué)習(xí)一下2022-01-01linux配置jdk環(huán)境變量簡(jiǎn)單教程
這篇文章主要為大家詳細(xì)介紹了linux配置jdk環(huán)境變量簡(jiǎn)單教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01