5
votes

I was trying to create JWT ("JOT") token for make my api call authentic. When ever I try creating token with RSA512 signature, I get back an error saying

java.lang.IllegalArgumentException: RSA signatures must be computed using an RSA PrivateKey. The specified key of type javax.crypto.spec.SecretKeySpec is not an RSA PrivateKey.

I am using below code:

 SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RS512;

 long nowMillis = System.currentTimeMillis();
  Date now = new Date(nowMillis);
 byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET_KEY);
 Key signingKey = new SecretKeySpec(apiKeySecretBytes, 
                signatureAlgorithm.getJcaName());

   JwtBuilder builder = Jwts.builder().claim("uuid", 
    id).setIssuedAt(now).setExpiration(new Date(600000))
    .signWith(signatureAlgorithm, signingKey);

Note : My "SECRET_KEY" is a string which is a private key generated randomly online . my questionis how can I get a Key object from a string encoded with RSA key size as 4096. 4096 since I am using RSA512 encryption, it is recommended to use 4096 key for RSA512

1
to verify your token on jwt.io you have to provide your secret in the right column under verify signature - your-256-bit-secret - jps
The error says something about the key type, but you didn't show details about the SECRET_KEY. Can you post the key? - jps
I used some random Secret key per say "adsfd564464gfasdf45ds4dffas56f4asd6fda45fads" - Kishore Jetty
that's sufficient for a HS secret, but certainly not a RSA key. A RSA key looks like this : -----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQDHikastc8+I81zCg/qWW8dMr8mqvXQ3qbPAmu0RjxoZVI47tvs...5vg087ZngKfFGR5rozDiTsK5DceTV97K a3Y+Nzl+XWTxDBWk4YPh2ZlKv402hZEfWBYxUDn5ZkH/bw== -----END RSA PRIVATE KEY----- On this site you can create keys for testing. - jps
Thanks for the info @jsp , it worked but looks like I am not providing right signature . , I was able to generate but still it says Invalid Signature @ jwt.io - Kishore Jetty

1 Answers

0
votes

Initially I was not providing an Base64 encoded RSAkey where I was encoding it again to base64 , reason why I was getting this error.

java.lang.IllegalArgumentException: RSA signatures must be computed using an RSA PrivateKey. The specified key of type javax.crypto.spec.SecretKeySpec is not an RSA PrivateKey.

I was getting back below error when ever I provide and RSAKey base 64 encoded or an byte code private key

Base64-encoded key bytes may only be specified for HMAC signatures. If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.

When ever I am providing a string /byte of private key, it is checking for HMAC algorithm all the time. see below code from JWTBuilder.

@Override
public JwtBuilder signWith(SignatureAlgorithm alg, byte[] secretKey) {
    Assert.notNull(alg, "SignatureAlgorithm cannot be null.");
    Assert.notEmpty(secretKey, "secret key byte array cannot be null or empty.");
    Assert.isTrue(alg.isHmac(), "Key bytes may only be specified for HMAC signatures.  If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.");
    this.algorithm = alg;
    this.keyBytes = secretKey;
    return this;
}

@Override
public JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey) {
    Assert.hasText(base64EncodedSecretKey, "base64-encoded secret key cannot be null or empty.");
    Assert.isTrue(alg.isHmac(), "Base64-encoded key bytes may only be specified for HMAC signatures.  If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.");
    byte[] bytes = TextCodec.BASE64.decode(base64EncodedSecretKey);
    return signWith(alg, bytes);
}

@Override
public JwtBuilder signWith(SignatureAlgorithm alg, Key key) {
    Assert.notNull(alg, "SignatureAlgorithm cannot be null.");
    Assert.notNull(key, "Key argument cannot be null.");
    this.algorithm = alg;
    this.key = key;
    return this;
}

Its always best Idea to provide an private Key of type java.security.key and must be a RSA key . I used P12 certificate to load private key.