rajanikanth
rajanikanth

Reputation: 153

Token generated using JWTSigner.sign() saying invalid signature in jwt.io debugger

We had written small API using java-jwt. It works fine when i create a token and verify the token in Java code.

  1. Created RSA Private and Public keys. (Referred to one of the test case)
  2. Created a token using Algorithm.RS256 with the private key.
  3. Verified the same token and got output as expected.

Then provided the public key to client and we started invoking their REST services using generated tokens. Client side using https://www.npmjs.com/package/jsonwebtoken to verify the tokens. They came back saying that the token and public key provided saying Invalid Signature in jwt.io debugger. They requested to make it work in jwt.io debugger first. I don't understand when it is working in Java code with the same public why is it saying that way in jwt.io. Am i missing something?

Generating Keys

public void createPemFiles(String absoluteFilePath) throws Exception {    
  logger.log(Level.INFO, "Received request to create Key pair : " + absoluteFilePath);
  PemWriter pemWriter = new PemWriter();
  // create key pair
  final KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");
  generator.initialize(KEY_SIZE);
  final KeyPair keyPair = generator.generateKeyPair();

  // write private key
  final RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  privateKeyPem = new File(absoluteFilePath);
  pemWriter.writePrivateKey(privateKey, "RSA PRIVATE KEY", privateKeyPem.getAbsolutePath());
  logger.log(Level.INFO, "Created private key  : " + privateKeyPem.getAbsolutePath());

  // write public key
  publicKeyPem = new File(absoluteFilePath+".pub");
  final RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  pemWriter.writePublicKey(publicKey, "RSA PUBLIC KEY", publicKeyPem.getAbsolutePath());
  logger.log(Level.INFO, "Created public key  : " + publicKeyPem.getAbsolutePath());
}

Create Token

public String createJWTToken(String [] keyValues) {
  final HashMap<String, Object> claims = new HashMap<String, Object>();
  String [] nameValue;

  for(String keyValue : keyValues) {
      nameValue = keyValue.split("##");
      claims.put(nameValue[0],nameValue[1]);
  }
  return JWTSIGNER.sign(claims, OPTIONS);
}

Verifying Token

public String verifyJWTToken(String token) throws  Exception{
  logger.log(Level.DEBUG, "Received request for verify JWT token");
  Map<String, Object> claims = JWTVERIFIER.verify(token);
  String claimString = "";

  String key = "";
  String value = "";

  for(Map.Entry<String, Object> entry : claims.entrySet()) {
      key = entry.getKey();
      value = (String) entry.getValue().toString();
      claimString = claimString + key +":"+ value + "##";
  }
  claimString = replaceLast(claimString, "##", "");
  logger.log(Level.DEBUG, "Successfully verified : "+claimString);
  return claimString;
}

Input

iccid:4454788545885968585##
nonce:5e452610c9f9decd:-404fb717:157fd6fc54e:-7ffe##
timestamp:2016-10-25T16:16:36.036Z

Created Token Output

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpY2NpZCI6IjQ0NTQ3ODg1NDU4ODU5Njg1ODUiLCJub25jZSI6IjVlNDUyNjEwYzlmOWRlY2Q6LTQwNGZiNzE3OjE1N2ZkNmZjNTRlOi03ZmZlIiwidGltZXN0YW1wIjoiMjAxNi0xMC0yNVQxNjoxNjozNi4wMzZaIn0.PlWVn1jlkvjRpw34-fsjJGQVVd74sFdg7SS2UgA4HUx4vBMYMA4b-Zzg5VxyzYkhzSsQqjKn7UBw04fXIwsmaP9A7Pc3-MjHjbmYT3Yv52qvH4yNy6X_M0z41UHuuLaWVQN3eck5BKIoO2cy4ihb8OOISkzF1Cf-Udx1GB-bVY4C4JtIvGpMflVW4hS9ZpWzKz26qlva7Y9KMEmvW24tviNcy8aVNyC55MS_KS_Ab7YWQ-MERRiNTCDIqUG7YVSN2Ap_SsNMab687GknQh78ibAowUdpLbGRU4N5EHZyG2lg-u-oL594fRA2anr-JunSxtpkI8-tKzR9NG5dt4F79Q

Verify Token Output

iccid:4454788545885968585##
nonce:5e452610c9f9decd:-404fb717:157fd6fc54e:-7ffe##
timestamp:2016-10-25T16:16:36.036Z

Public Key

-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx58WGD/wRFnwe64sl/9V
KuNOQChYUy8GfhQU66M2XSnx/UpjPCqhGYRmpUXT+rQAamUDsarGt8Kbw1DtlvLT
p2UTvSWiCJNQzi53CRa6iDbk213Ps7zuAFhuXB7s0ZqdOZbeJnXFFM/wMJbM6kdB
yAdCwj8/kCKCjSt3Q0CLdxaToTucRJuO7/V4wbJIDMfLt3LPlry/PsHQAx0RKXco
TO1JsSGWg99dHBEqpxLMBtZyhyd8++PrMrtQ4pPVAmXoJODKY2NZkiLl3h4Ai48z
FhBNHsWQDTJKA8skb2JQER9i1a1/ip/cgkR6FG6G65DbhrMElcL0mgdst49PF26p
pwIDAQAB
-----END RSA PUBLIC KEY-----

Upvotes: 2

Views: 5586

Answers (1)

Jo&#227;o Angelo
Jo&#227;o Angelo

Reputation: 57728

It seems jwt.io expects a Public Key file (PKCS#8):

-----BEGIN PUBLIC KEY-----
BASE64 DATA
-----END PUBLIC KEY-----

instead of the RSA Public Key file (PKCS#1) you're passing:

-----BEGIN RSA PUBLIC KEY-----
BASE64 DATA
-----END RSA PUBLIC KEY-----

The interesting bit is that if you manually edit your file to replace the RSA PUBLIC KEY marker with just PUBLIC KEY marker then you'll get a verified signature. This is curious because the BASE64 data would be different according to the format, however, I didn't look into the details to find how if there's any culprit so don't ask me why, but that will work.

Upvotes: 5

Related Questions