This post will help you to generate a self-signed certificate and show you how to validate the JWT token using Nimbus Jose JWT library.
package com.varra.samples;
import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Date;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import sun.security.rsa.RSAPublicKeyImpl;
import sun.security.x509.AlgorithmId;
import sun.security.x509.CertificateAlgorithmId;
import sun.security.x509.CertificateSerialNumber;
import sun.security.x509.CertificateValidity;
import sun.security.x509.CertificateVersion;
import sun.security.x509.CertificateX509Key;
import sun.security.x509.X500Name;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;
public class JWTTokenUtils {
	/** 
	 * Create a self-signed X.509 Certificate
	 * @param dn the X.509 Distinguished Name, eg "CN=RK, L=Hyderabad, C=Hyderabad"
	 * @param pair the KeyPair
	 * @param days how many days from now the Certificate is valid for
	 * @param algorithm the signing algorithm, eg "SHA1withRSA"
	 */ 
	public static X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm)
	  throws GeneralSecurityException, IOException
	{
	  PrivateKey privkey = pair.getPrivate();
	  X509CertInfo info = new X509CertInfo();
	  Date from = new Date();
	  Date to = new Date(from.getTime() + days * 86400000l);
	  CertificateValidity interval = new CertificateValidity(from, to);
	  BigInteger sn = new BigInteger(64, new SecureRandom());
	  X500Name owner = new X500Name(dn);
	 
	  info.set(X509CertInfo.VALIDITY, interval);
	  info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
	  //info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
	  info.set(X509CertInfo.SUBJECT, owner);
	  info.set(X509CertInfo.ISSUER, owner);
	  info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
	  info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
	  AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
	  info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
	 
	  // Sign the cert to identify the algorithm that's used.
	  X509CertImpl cert = new X509CertImpl(info);
	  cert.sign(privkey, algorithm);
	 
	  // Update the algorith, and resign.
	  algo = (AlgorithmId)cert.get(X509CertImpl.SIG_ALG);
	  info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo);
	  cert = new X509CertImpl(info);
	  cert.sign(privkey, algorithm);
	  return cert;
	}
	
	public static String generateToken(RSAPrivateKey privateKey) throws Exception
	{
		// Create RSA-signer with the private key
		final JWSSigner signer = new RSASSASigner(privateKey);
		
		// Prepare JWT with claims set
		final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
		    .subject("alice")
		    .issuer("Rajakrishna Reddy")
		    .claim("user", "Rajakrishna Reddy")
		    .claim("tenantId", "123")
		    .expirationTime(new Date(new Date().getTime() + 60 * 1000))
		    .build();
		final SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256), claimsSet);
		signedJWT.sign(signer);
		return signedJWT.serialize();
	}
	
	public static boolean isValidToken(String token, RSAPublicKey publicKey) throws Exception
	{
		return SignedJWT.parse(token).verify(new RSASSAVerifier(publicKey));
	}
	
	public static boolean isValidToken(String token, String publicKey) throws Exception
	{
		byte[] decoded = Base64.getDecoder().decode(publicKey);
	    X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded);
	    KeyFactory kf = KeyFactory.getInstance("RSA");
	    RSAPublicKey generatePublic = (RSAPublicKey) kf.generatePublic(spec);
	    BigInteger modulus = generatePublic.getModulus();
	    BigInteger exponent = generatePublic.getPublicExponent();
	    return SignedJWT.parse(token).verify(new RSASSAVerifier(new RSAPublicKeyImpl(modulus, exponent)));
		//return SignedJWT.parse(token).verify(new RSASSAVerifier(publicKey));
	}
	
	public static void main(String[] args) throws Exception {
		final String algorithmType = "RSA";
		final String algorithm = "SHA256withRSA";
		final String dn = "CN=Rajakrishna Reddy, OU=OU, O=varra, L=Hyderabad, ST=TL, C=IN";
		final int days = 365;
		final KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(algorithmType);
		keyGenerator.initialize(2048);
		final KeyPair kp = keyGenerator.genKeyPair();
		
		final X509Certificate certificate = generateCertificate(dn, kp, days, algorithm);
		System.out.println("X09.Certificate: "+certificate);
		//final String token = generateToken((RSAPrivateKey) kp.getPrivate());
		final String token = "eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE1MjUyNDUyMDAsInN1YiI6IkpXVCIsInVzZXJfbWV0YWRhdGEiOiJ7XCJVc2VybmFtZVwiOlwibWNzYVwifSIsImlhdCI6MTUyNTE1ODgwMH0.wbroKZfrdGPGnk3OaPWbRr56rRzkg4DFO999jmSsut8IYAthKU0f26CIjWfrNPXD5asV74JYIS49VFNkFwbWfnIFETY1CaLIIm6F6NP5cFE7LW5G-y0qNRaCJgOLaFV4z4lsQOi0KAfuFVckiL5EHxhyBks-MCQEXMWO2JIBBZjAxhIH7fmhMHsYQQUxvm8Tx1dpnbvyh9E6x5F9BNZeS2DcBCqvzCuSUAz2DbgsJ-gVyrDRJgcItiCnscZy2u3sZq3XBTK2qBiSIpS4zVZupVS0f-5v57y7BvdVX2siuu-StN5614zvON_MJRgNLdo1yA1Y5F8eJ9IZrelMWB5GZw";
		final String publiKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2hg1nqteEY12r5AO/enYD14aXEUaoqgvhtcHDwEPQwf9KqGpwoeC8jQE1qHfb2K1Wm/o4ug60Kv02f7AEJiNrUuKe9MYJdTr/DhekVrE0ttJkGCjLoNiVgMZHKH557Ouf6RsWJc5QjUiqxg6azwYUuHu2U199MZzFXvAVVUQR+hh8YqQM4KIQytOpj1JhxH7hQehth9vF5kIhA+K8htIIO04UF9+8ScrBHMQgj9q0RLperVQLxGsYT8cEZIn9tv1r47jynrTS0z/Vq2uVMGRg/bRPuo598++XUIglM92Ehbih87j//ATcHtsabefzBAVQuN4OaqLTT375JRAWpoWmQIDAQAB";
		System.out.println("Token: "+token);
		//System.out.println("Is valid?: "+isValidToken(token, (RSAPublicKey) kp.getPublic()));
		System.out.println("Is valid?: "+isValidToken(token, publiKey));
		
		//System.out.println(isValidToken(token, CertificateUtil.parseRSAPublicKey()));
		
	}
}