JSON web token is a way to transfer data between two parties securely and safely. The signature of the JWT token guarantees that JWT token is produced by an authentic provider. You can use it in your service for authentication and authorization purposes. Let’s learn to create a JWT token in Java and then verify the signature of the JWT token.
RSA256 Algorithm
RSA256 is an asymmetric algorithm that requires both public and private keys. It is more secure because the private key is safe and not shared with the clients.
- A Private Key is required to sign the JWT token
- A public Key is needed to verify the signature of the JWT token.
Generate Public and Private JWT keys
There are multiple ways with which you can generate Public and private keys for JWT. we will be using an online tool for this. visit the website for generating the keys.
https://acte.ltd/utils/openssl
You need to select the options from the list and then click on Generate Keys
- Algorithm:Â RSA
- size:Â 2048
- Leave the passphrase empty
After clicking the GENERATE KEYS button click on the PKCS8 format. You will see the public and private keys at the bottom of the screen
Copy the public key and private key from the website which we generated earlier and then save them inside the resources folder of our project
- private_key.pem
- public_key.pem
The private key that we are using is
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCgf5FzsDlpQmsn
mYFUgH5Zmie9i1XvbcPcXKo7RWS8dD6sGvSUA47I0CSi4Q+W+7hHnp9RnNxFWpNz
+/ZZ56bkCBSG0NMcc9j76AV9YkKbeK8DdSGhKji7ZaBxSv1atI6Qdnz2ascgjS6B
nloukHFRDUlpOOj66YXS7uHYNTXla2H69VYvgqA07GlAUKBA3LB7VDGa5irWIRlG
xI/73EsSBpv5T9mrGCFkTurOY27XDzm9bLwXZAwB59RAAwGcHjtDLSsTDLfEx04u
5t+woBbNZ71JRMCtHWmXPNr6i2958BdUFs6kTJTqlhZMZaFfmT2+5Sr7xRQS4tyy
w7xeCCE1AgMBAAECggEAFQRfgazD99qwuYDKhMxGv2kGZzXFzRKsoUCpMhXGOT9n
rZXiDTfiDL3k7kdWiUjxOr+00TUfSx2vTXLjMaa6HgZI2dairoklEuexQFgLrNxC
3ssJ2lbzEucd+Xf+cVBPku9RMduNs9+JBYQ8/vf/PsPkpxjCuYi284ZAoNVm92HB
Xezg6YXp2urMC3GD1lO1rFa6mrbxGRLMzJ6OHk5wV1UvG62psXeAvJ9WQ6FtB1lv
Z/WGM018v56FWhE7+CjC0eQ93DdySvPsYLdoKIBJg4533W8l2CjVfwrjSIiif71d
0Z3u62cDHVhM/rcXjrcejHgrMVEBAn2xh5FpOikOgQKBgQDMdjBS0qGH4EL9a9+4
aMmV8OdOrRJj94bfpbsEUngQ85sUR8HDHHPoXQBgEHvjFL01G5mXWk/2j9ivS2iI
7xSkgV3dIGmp/zrFT3KveaYAzpZ1Y961HqMnsdUBsaKMHvLtIL3QT91Oe8J3iU2V
xVhiAM8o77N/ZMwTtP1x8bk5hQKBgQDI9HIAXirLGzCkJDghiiwpJ+pDWxPqqjlm
sIIn00GLnvD5zAVd4GY67xUut7WICXsKnb17dY5D8nf/Sungnw4nSw4iNBq3UBKM
6SAKwEzkqVNbOpAB6Y7KZryOT0u2qLrG1nb8gAxIv74h7G9/ljxn5ULSksZHyy6W
uFy6mKB/8QKBgBMmNpxrMcnCDUQi6E8jMU4jw+Ywe3p1YmJr6TocZzZfOnUJy3H0
pj5rB2/320KHXLkunpH4WWjkTA0O6Pl6Otq1aw8czAip6N019a3NnOiScLEJ63/X
ILzFAQgplOm+tE3VNTHfaQDCwpHjgCq40vBK1xwkZxFVZW+rEdmsJAbpAoGAXwFy
hEoA4VVRgci94N16U1rTnlSI7gDccngwkLOH4YKbWv3h66gTrPkrgpLH+DDDQxmg
Y6YIRId1w/Se7dtEzb7mR7VqjBAHNSdiRrLzp4eGKTNesgjBwV8g9gb3PLw40ZjD
WE0RgbNlKJSngiJ9HIF/Ph62L2sX85nl/TH7b4ECgYEArZa0IdRvw/Zbu6aKc7SM
alPEC1LXsI4DZTjAuSyrE/A7I/UaBsqwjru1JWT0cFbsMWTI0+hhNgykqsD4mlGh
q97FB53jbol4rTkKRGskAiSn8fEiC/JMN+XbWv7AjMfe9Dv8mhfOl44LcQXvghoB
hmpYYLiidCu4798aiIYNRFA=
-----END PRIVATE KEY-----
The public key that we are using is
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoH+Rc7A5aUJrJ5mBVIB+
WZonvYtV723D3FyqO0VkvHQ+rBr0lAOOyNAkouEPlvu4R56fUZzcRVqTc/v2Weem
5AgUhtDTHHPY++gFfWJCm3ivA3UhoSo4u2WgcUr9WrSOkHZ89mrHII0ugZ5aLpBx
UQ1JaTjo+umF0u7h2DU15Wth+vVWL4KgNOxpQFCgQNywe1QxmuYq1iEZRsSP+9xL
Egab+U/ZqxghZE7qzmNu1w85vWy8F2QMAefUQAMBnB47Qy0rEwy3xMdOLubfsKAW
zWe9SUTArR1plzza+otvefAXVBbOpEyU6pYWTGWhX5k9vuUq+8UUEuLcssO8Xggh
NQIDAQAB
-----END PUBLIC KEY-----
Java Dependency for JWT
You are required to add the auth0 java-jwt library to your project as a dependency.
implementation 'com.auth0:java-jwt:4.4.0'
Read Private and Public JWT key
The private and public keys are stored in the resources folder under the name private_key.pem and public_key.pem.
Create a method to read the Public key
public static RSAPublicKey getPublicKey() throws Exception {
try {
String publicKeyContent = new String(Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("public_key.pem").toURI())),Charset.defaultCharset());
publicKeyContent = publicKeyContent.replaceAll("\\n", "").replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "");
byte[] encoded = Base64.getDecoder().decode(publicKeyContent);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
Create a method to read the Private key
public static RSAPrivateKey getPrivateKey() throws Exception {
try {
String privateKeyContent = new String(Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("private_key.pem").toURI())),Charset.defaultCharset());
privateKeyContent = privateKeyContent.replaceAll("\\n", "").replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "");
privateKeyContent = privateKeyContent.replaceAll("\\s", "");
byte[] encoded = Base64.getDecoder().decode(privateKeyContent);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
Generate and Verify the JWT token
We will use the public and private key and RSA256 Algorithm to generate the JWT token
Algorithm algorithm = Algorithm.RSA256(getPublicKey(), getPrivateKey());
String token = JWT.create()
.withIssuer("cwrr-playground")
.withClaim("firstName", "Raj")
.withClaim("lastName", "Ranjan")
.withClaim("email", "raj.ranjan91956@gmail.com")
.withClaim("id", "100")
.withExpiresAt(new Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5)))
.sign(algorithm);
One sample token generated is presented below
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjd3JyLXBsYXlncm91bmQiLCJmaXJzdE5hbWUiOiJSYWoiLCJsYXN0TmFtZSI6IlJhbmphbiIsImVtYWlsIjoicmFqLnJhbmphbjkxOTU2QGdtYWlsLmNvbSIsImlkIjoiMTAwIiwiZXhwIjoxNzE1OTUyMTEwfQ.AWUv5yz8g63WuDOPujA05dWuDiLttgEUUBx65R8hRRE67H8lh77UPJZhO6RJqeGrxXiTL7k0KDr2LAa1dxvak38ClKzC-OJg2i4r42aCIgaVkD-TioMUtKp8Bp0Tgtv_XkPP-hqqK2nXn0XrTAH8FS8RzECJ8lfjidp6K8BGPFHUAXfL-P3i2B2KbwdOJERWuNTn65OC8xFj6d6bPoOStR4VmwiAGd_Yg1xYenuaavGc1X4m6QiXfryB1SHUZOOjty_rKB3RhXqvjdRUZPgWZ5APqBk7LJlHyyeHkfCGVjgEMjcr0fOzN_eYLrdOe68TYBLFVa78e9-YhkV228xewQ
You will see that that JWT token has three parts separated by dots (.)
- The first part is the header
- The second part is the payload or body
- The third part is the signature
You can verify the signature of the token using the JWT Verified
try {
Algorithm algorithm = Algorithm.RSA256(getPublicKey(), getPrivateKey());
JWTVerifier verifier = JWT.require(algorithm)
.build();
DecodedJWT decodedJWT = verifier.verify(token);
System.out.println(decodedJWT.getClaim("firstName"));
} catch (Exception e) {
e.printStackTrace();
throw e;
}
Complete Code for Java JWT Token Generation and Verification
package cwrr.playground;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.sql.Date;
import java.util.Base64;
import java.util.concurrent.TimeUnit;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
public class App {
public static void main(String[] args) throws IllegalArgumentException, Exception {
Algorithm algorithm = Algorithm.RSA256(getPublicKey(), getPrivateKey());
String token = JWT.create()
.withIssuer("cwrr-playground")
.withClaim("firstName", "Raj")
.withClaim("lastName", "Ranjan")
.withClaim("email", "raj.ranjan91956@gmail.com")
.withClaim("id", "100")
.withExpiresAt(new Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5)))
.sign(algorithm);
try {
JWTVerifier verifier = JWT.require(algorithm)
.build();
DecodedJWT decodedJWT = verifier.verify(token);
System.out.println(decodedJWT.getClaim("firstName"));
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
public static RSAPublicKey getPublicKey() throws Exception {
try {
String publicKeyContent = new String(Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("public_key.pem").toURI())),Charset.defaultCharset());
publicKeyContent = publicKeyContent.replaceAll("\\n", "").replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "");
byte[] encoded = Base64.getDecoder().decode(publicKeyContent);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
public static RSAPrivateKey getPrivateKey() throws Exception {
try {
String privateKeyContent = new String(Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("private_key.pem").toURI())),Charset.defaultCharset());
privateKeyContent = privateKeyContent.replaceAll("\\n", "").replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "");
privateKeyContent = privateKeyContent.replaceAll("\\s", "");
byte[] encoded = Base64.getDecoder().decode(privateKeyContent);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}