JWS and JWT with Google Cloud KMS

Google Cloud KMS is a service for storing and generating cryptographic keys where the critical operations signing, encryption and decryption are done behind the service API, to prevent exposure and potential leaks of the underlying keys by the application. Note, the KMS is not a 100% guarantee against unauthorised signing and en/decryption if an application is compromised to drive the KMS API and then caused to extract the signatures / decrypted plaintext.

Amazon has a similar service called AWS KMS.

The Google Cloud KMS provider for Nimbus JOSE+JWT

If you're looking for a way to mint signed JWTs with the Google's KMS check out the Google Cloud KMS provider for Nimbus JOSE+JWT. It comes with an open source Apache 2.0 license.

JWS algorithms

At the time of writhing this the following JWS algorithms are supported:

  • RSA:
    • RS256 with 2048, 3072 and 4096 bit keys
    • RS512 with 4096 bit keys
    • PS256 with 2048, 3072 and 4096 bit keys
    • PS512 with 4096 bit keys
  • ECDSA:
    • ES256
    • ES384
  • HMAC:
    • HS256

Signing

Signing is implemented via the simple JWSSigner interface. The application code is expected to create a KmsKeyHandle which then can be used to construct JWSHeaders with the appropriate algorithm and key ID for the underlying key in the KMS, and to perform the actual signing by invoking the KMS web API.

For a JWT:

// Create the KMS handle via factory
KmsKeyHandle handle = ...

// Create JWS header and sign the JWT
JWSHeader header = handle.createHeaderBuilder().build();
SignedJWT jwt = new SignedJWT(header, claims);
jwt.sign(handler.getSigner());

If you are curious what happens behind the scenes - the signing with the KMS is performed by passing the signing key reference, algorithm and SHA hash of the payload to the service. On success the KMS will return the computed signature bytes for the JWS.

Note, signing with the KMS involves a network round-trip and because of this the latency will not be the same as compared to local signing.

Verification

The JWSVerifier interface is also implemented which can be suitable for applications that consume their own tokens.

If the tokens get consumed by other applications the standard approaches apply, such as publishing the public JWKs at an endpoint.