Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Sample analysis of the project on the use of open source JWT libraries

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

Project on the use of open source JWT library example analysis, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain in detail for you, people with this need can come to learn, I hope you can get something.

In the past, I have been using jjwt as a JWT library, which is small enough, but it does not encapsulate some of the details of JWT very well. Recently, a better JWT library, nimbus-jose-jwt, has been discovered, which is easy to use, API is very easy to understand, and supports both symmetric and asymmetric encryption algorithms.

Nimbus-jose-jwt is the most popular JWT open source library, based on the Apache 2.0 open source protocol, supporting all standard signature (JWS) and encryption (JWE) algorithms.

JWT conceptual relationship here we need to understand the relationship among JWT, JWS, and JWE. In fact, JWT (JSON Web Token) refers to a specification that allows us to use JWT to transmit secure and reliable information between two organizations. JWS (JSON Web Signature) and JWE (JSON Web Encryption) are two different implementations of the JWT specification, and the most commonly used implementation is JWS.

Next, we introduce the use of nimbus-jose-jwt library, which mainly uses symmetric encryption (HMAC) and asymmetric encryption (RSA) to generate and parse JWT tokens.

Symmetric encryption (HMAC) symmetric encryption refers to the use of the same secret key for encryption and decryption, if your secret key does not want to be exposed to the decryptor, consider using asymmetric encryption.

To use the nimbus-jose-jwt library, first add related dependencies to pom.xml

Com.nimbusds nimbus-jose-jwt 8.16 Copy to clipboardErrorCopied creates JwtTokenServiceImpl as a business class processed by JWT, and adds a method to generate and parse JWT tokens according to HMAC algorithm. You can find that the API of JWT operated by nimbus-jose-jwt library is very easy to understand; / * Created by macro on 2020-6-22. * / [@ Service] (https://my.oschina.net/service) public class JwtTokenServiceImpl implements JwtTokenService {[@ Override] (https://my.oschina.net/u/1162528) public String generateTokenByHMAC (String payloadStr, String secret) throws JOSEException {/ / create JWS header, set signature algorithm and type JWSHeader jwsHeader = new JWSHeader.Builder (JWSAlgorithm.HS256). Type (JOSEObjectType.JWT) .build (); / encapsulate load information in Payload Payload payload = new Payload (payloadStr); / / create JWS object JWSObject jwsObject = new JWSObject (jwsHeader, payload); / / create HMAC signer JWSSigner jwsSigner = new MACSigner (secret); / / sign jwsObject.sign (jwsSigner); return jwsObject.serialize ();}

[@ Override] (https://my.oschina.net/u/1162528)public PayloadDto verifyTokenByHMAC (String token, String secret) throws ParseException, JOSEException {/ / parse JWS object JWSObject jwsObject = JWSObject.parse (token) from token; / / create HMAC verifier JWSVerifier jwsVerifier = new MACVerifier (secret); if (! jwsObject.verify (jwsVerifier)) {throw new JwtInvalidException ("token signature is invalid!") ;} String payload = jwsObject.getPayload (). ToString (); PayloadDto payloadDto = JSONUtil.toBean (payload, PayloadDto.class); if (payloadDto.getExp () < new Date (). GetTime ()) {throw new JwtExpiredException ("token expired!") ;} return payloadDto;}

} Copy to clipboardErrorCopied creates PayloadDto entity classes, which are used to encapsulate information stored in JWT; / * *

Created by macro on 2020-6-22. / @ Data @ EqualsAndHashCode (callSuper = false) @ Builder public class PayloadDto {@ ApiModelProperty ("subject") private String sub; @ ApiModelProperty ("issue time") private Long iat; @ ApiModelProperty ("expiration time") private Long exp; @ ApiModelProperty ("JWT's ID") private String jti; @ ApiModelProperty ("user name") private String username; @ ApiModelProperty ("user permissions") private List authorities } Copy to clipboardErrorCopied adds a method to get the default PayloadDto in the JwtTokenServiceImpl class, and the JWT expiration time is set to 60min / *

Created by macro on 2020-6-22. / @ Service public class JwtTokenServiceImpl implements JwtTokenService {@ Override public PayloadDto getDefaultPayloadDto () {Date now = new Date (); Date exp = DateUtil.offsetSecond (now, 6060); return PayloadDto.builder () .sub ("macro") .iat (now.getTime ()) .exp (exp.getTime ()) .jti (UUID.randomUUID (). ToString ()) .username ("macro") .authorities (CollUtil.toList ("ADMIN")) .build () }} Copy to clipboardErrorCopied creates the JwtTokenController class and adds an interface to generate and parse JWT tokens according to the HMAC algorithm. Since the HMAC algorithm requires a secret key at least 32 bytes long, we use MD5 encryption / * *

JWT token Management Controller

Created by macro on 2020-6-22. * / @ Api (tags = "JwtTokenController", description = "JWT token Management") @ Controller @ RequestMapping ("/ token") public class JwtTokenController {

@ Autowired private JwtTokenService jwtTokenService

@ ApiOperation ("generate token using symmetric encryption (HMAC) algorithm") @ RequestMapping (value = "/ hmac/generate", method = RequestMethod.GET) @ ResponseBody public CommonResult generateTokenByHMAC () {try {PayloadDto payloadDto = jwtTokenService.getDefaultPayloadDto (); String token = jwtTokenService.generateTokenByHMAC (JSONUtil.toJsonStr (payloadDto), SecureUtil.md5 ("test")); return CommonResult.success (token);} catch (JOSEException e) {e.printStackTrace ();} return CommonResult.failed ();}

@ ApiOperation ("verify token using symmetric encryption (HMAC) algorithm") @ RequestMapping (value = "/ hmac/verify", method = RequestMethod.GET) @ ResponseBody public CommonResult verifyTokenByHMAC (String token) {try {PayloadDto payloadDto = jwtTokenService.verifyTokenByHMAC (token, SecureUtil.md5 ("test")); return CommonResult.success (payloadDto);} catch (ParseException | JOSEException e) {e.printStackTrace ();} return CommonResult.failed ()

}} Copy to clipboardErrorCopied calls the interface that uses the HMAC algorithm to generate JWT tokens for testing

Call the interface that parses the JWT token using the HMAC algorithm for testing.

Asymmetric encryption (RSA) asymmetric encryption refers to the use of public and private keys for encryption and decryption operations. For the encryption operation, the public key is responsible for encryption, the private key is responsible for decrypting, for the signature operation, the private key is responsible for signing, and the public key is responsible for verification. The use of asymmetric encryption in JWT is clearly a signature operation.

If we need to sign and verify with fixed public and private keys, we need to generate a certificate file, which will be generated using the keytool tool that comes with Java, which is located in JDK's bin directory.

Open the CMD command interface, use the following command to generate the certificate file, set the alias to jwt, the file name is jwt.jks; keytool-genkey-alias jwt-keyalg RSA-keystore jwt.jks Copy to clipboardErrorCopied, enter the password 123456, and then enter various information to generate the certificate jwt.jks file.

Copy the certificate file jwt.jks to the project's resource directory, and then you need to read RSAKey from the certificate file. Here we need to add a RSA dependency of Spring Security to pom.xml.

Org.springframework.security spring-security-rsa 1.0.7.RELEASE Copy to clipboardErrorCopied then adds a method to the JwtTokenServiceImpl class to read the certificate file from the classpath and convert it to a RSAKey object; / * Created by macro on 2020-6-22. * / @ Service public class JwtTokenServiceImpl implements JwtTokenService {@ Override public RSAKey getDefaultRSAKey () {/ / obtain the RSA key pair KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory (new ClassPathResource ("jwt.jks"), "123456" .toCharray ()) from classpath; KeyPair keyPair = keyStoreKeyFactory.getKeyPair ("jwt", "123456" .toCharArray ()); / / obtain the RSA public key RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic (); / / obtain the RSA private key RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate () Return new RSAKey.Builder (publicKey) .privateKey (privateKey). Build ();}} Copy to clipboardErrorCopied We can add an interface to JwtTokenController to obtain the public key in the certificate / * JWT token Management Controller * Created by macro on 2020-6-22. * / @ Api (tags = "JwtTokenController", description = "JWT token Management") @ Controller @ RequestMapping ("/ token") public class JwtTokenController {

@ Autowiredprivate JwtTokenService jwtTokenService;@ApiOperation ("get the public key of asymmetric encryption (RSA) algorithm") @ RequestMapping (value = "/ rsa/publicKey", method = RequestMethod.GET) @ ResponseBodypublic Object getRSAPublicKey () {RSAKey key = jwtTokenService.getDefaultRSAKey (); return new JWKSet (key). ToJSONObject ();}

} Copy to clipboardErrorCopied calls this API to view public key information, which can be accessed publicly.

By adding the method of generating and parsing JWT tokens according to RSA algorithm in JwtTokenServiceImpl, you can find that the operation is basically the same as that of HMAC algorithm above; / * *

Created by macro on 2020-6-22. * / @ Service public class JwtTokenServiceImpl implements JwtTokenService {@ Override public String generateTokenByRSA (String payloadStr, RSAKey rsaKey) throws JOSEException {/ / create JWS header, set signature algorithm and type JWSHeader jwsHeader = new JWSHeader.Builder (JWSAlgorithm.RS256) .type (JOSEObjectType.JWT) .build (); / encapsulate payload information in Payload Payload payload = new Payload (payloadStr); / / create JWS object JWSObject jwsObject = new JWSObject (jwsHeader, payload); / / create RSA signer JWSSigner jwsSigner = new RSASSASigner (rsaKey, true) / / sign jwsObject.sign (jwsSigner); return jwsObject.serialize ();}

@ Override public PayloadDto verifyTokenByRSA (String token, RSAKey rsaKey) throws ParseException, JOSEException {/ / parse JWS object JWSObject jwsObject = JWSObject.parse (token) from token; RSAKey publicRsaKey = rsaKey.toPublicJWK (); / / create RSA verifier JWSVerifier jwsVerifier = new RSASSAVerifier (publicRsaKey) with RSA public key; if (! jwsObject.verify (jwsVerifier)) {throw new JwtInvalidException ("token signature is invalid!") ;} String payload = jwsObject.getPayload (). ToString (); PayloadDto payloadDto = JSONUtil.toBean (payload, PayloadDto.class); if (payloadDto.getExp () < new Date (). GetTime ()) {throw new JwtExpiredException ("token expired!") ;} return payloadDto;}} Copy to clipboardErrorCopied in the JwtTokenController class, add the interface for generating and parsing JWT tokens according to the RSA algorithm, using the default RSA key pair; / * *

JWT token Management Controller

Created by macro on 2020-6-22. * / @ Api (tags = "JwtTokenController", description = "JWT token Management") @ Controller @ RequestMapping ("/ token") public class JwtTokenController {

@ Autowired private JwtTokenService jwtTokenService

@ ApiOperation ("generate token using asymmetric encryption (RSA) algorithm") @ RequestMapping (value = "/ rsa/generate", method = RequestMethod.GET) @ ResponseBody public CommonResult generateTokenByRSA () {try {PayloadDto payloadDto = jwtTokenService.getDefaultPayloadDto (); String token = jwtTokenService.generateTokenByRSA (JSONUtil.toJsonStr (payloadDto), jwtTokenService.getDefaultRSAKey ()); return CommonResult.success (token);} catch (JOSEException e) {e.printStackTrace ();} return CommonResult.failed ();}

@ ApiOperation ("verify token using asymmetric encryption (RSA) algorithm") @ RequestMapping (value = "/ rsa/verify", method = RequestMethod.GET) @ ResponseBody public CommonResult verifyTokenByRSA (String token) {try {PayloadDto payloadDto = jwtTokenService.verifyTokenByRSA (token, jwtTokenService.getDefaultRSAKey ()); return CommonResult.success (payloadDto);} catch (ParseException | JOSEException e) {e.printStackTrace ();} return CommonResult.failed ();} Copy to clipboardErrorCopied calls the interface that generates JWT tokens using RSA algorithm for testing

Call the interface that parses the JWT token using the RSA algorithm for testing.

Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report