I would like to know the process of creation and verification of JWT signature using public and private keys in spring boot security.
I am trying to validate JWT token using HMAC algorithm. I am building JWT with hardcoded secret "MYSECRET".
Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setAudience(audience)
.setIssuedAt(createdDate)
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, "MYSECRET")
.compact()
For parsing the code is as follows
Jwts.parser()
.setSigningKey("MYSECRET")
.parseClaimsJws(token)
.getBody();
Instead of using signing key as "MYSECRET", I would like to make use of public and private keys
jsonwebtoken allows you to provide a certificate that will be used to verify JWTs, once you fetch a JWK to use (as explained above) you can then convert it to a key string by using a library or an online service (since this is a public key there is no risk in using an online service).
Security-wise, SWT can only be symmetrically signed by a shared secret using the HMAC algorithm. However, JWT and SAML tokens can use a public/private key pair in the form of a X.509 certificate for signing.
The jwt token is signed using private key. The auth server provides the public key publicly on a url in the form of JSON Web Key Set(JWKS). During verification the public keys are fetched. Here is an example of JWKS.
For Spring Boot Security database authentication please refer here. We are going to cover – Spring Boot Security with JWT Example – Token Generation, Token Validation and Token Refresh. What is JWT? JWT stands for Json Web Token which is a token implementation in JSON format. Json tokens used for authentication and data sharing between parties.
Then we set the signature part of the token. This is done using the signWith () method, we set the hashing algorithm we prefer to use and the secret key. Then we use thecompact () method that builds the JWT and serializes it to a compact, URL-safe string according to the JWT Compact Serialization rules.
The public key can be shared to any party that want to send sensitive data to the recipient. The encryption is rarely used with JWT. Most of the time the HTTPS layer is sufficient and the token itself only contain a few information that are not sensitive (datatime, IDs...).
The authentication server verifies the credentials and issues a jwt signed using either a secret salt or a private key. User’s Client uses the JWT to access protected resources by passing the JWT in the HTTP Authorization header. The resource server then verifies the authenticity of the token using the secret salt/ public key.
Let’s first generate the keys – and more specifically a .jks file – using the command line tool keytool:
keytool -genkeypair -alias mytest -keyalg RSA -keypass mypass -keystore mytest.jks -storepass mypass
keytool -list -rfc --keystore mytest.jks | openssl x509 -inform pem -pubkey
Using your key to sign token in your Authorization Server.
@Bean
public JwtAccessTokenConverter accessTokenConverter(){
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyStoreKeyFactory keyStoreKeyFactory =
new KeyStoreKeyFactory(new ClassPathResource("mytest.jks"), "mypass".toCharArray());
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("mytest"));
return converter;
}
Finally using your public key in your resource server.
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
Resource resource = new ClassPathResource("public.txt");
String publicKey = null;
try {
publicKey = IOUtils.toString(resource.getInputStream());
} catch (final IOException e) {
throw new RuntimeException(e);
}
converter.setVerifierKey(publicKey);
return converter;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With