Creating Signed JWTs using Nimbus JOSE + JWT
source link: https://www.scottbrady91.com/kotlin/creating-signed-jwts-using-nimbus-jose-jwt
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Creating Signed JWTs using Nimbus JOSE + JWT
I’ve been using the Java library “Nimbus JOSE + JWT” to create JWTs recently. It has been pretty useful for playing around with uncommon JOSE algorithms such as ES256K and EdDSA. Considering that these are not supported out-of-the-box in .NET yet, being able to use another stack to generate test data has been invaluable.
So, this is one of those blog posts where I write down how to use the library for signature generation and validation for future Scott to reference once he inevitably forgets.
Installation
To install Nimbus JOSE + JWT, you’ll need the nimbus-jose-jwt package from Maven. Here’s a snippet from my build.gradle:
repositories {
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation "com.nimbusds:nimbus-jose-jwt:7.8.1"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
JWT Signed using ECDSA
In this example, I’m going to create an EC key suitable for ES256K (curve secp256k1 with SHA-256), sign a JWT using my new private key, and verify the JWT signature with the corresponding public key.
Creating an EC Key
To generate a private key for our curve, I’m going to use ECKeyGenerator
.
I’ll also supply a key ID as if we were going to share the JWT and share the public key as a JWK.
val key: ECKey = ECKeyGenerator(Curve.P_256K)
.keyID("123")
.generate()
Nimbus JOSE + JWT uses the Java Cryptography Architecture (JCA). So, if you need or want to use Bouncy Castle instead, you can do so via the JCA.
Signing a JWT
To generate a JWT, I need to create a header and a payload, use them to generate a SignedJWT
, sign it using my private key, and then serialize the JWT into a URL-safe string.
val header = JWSHeader.Builder(JWSAlgorithm.ES256K)
.type(JOSEObjectType.JWT)
.keyID(key.keyID)
.build();
val payload = JWTClaimsSet.Builder()
.issuer("me")
.audience("you")
.subject("bob")
.expirationTime(Date.from(Instant.now().plusSeconds(120)))
.build()
val signedJWT = SignedJWT(header, payload)
signedJWT.sign(ECDSASigner(key.toECPrivateKey()))
val jwt: String = signedJWT.serialize()
Example ES256K JWT
eyJraWQiOiIxMjMiLCJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJhdWQiOiJ5b3UiLCJzdWIiOiJib2IiLCJpc3MiOiJtZSIsImV4cCI6MTU3NTEyODg5NX0.ha2bS5LynJ9nb7HxElJtzZ9hK4Z9LwvHcPcZHFLdpf1fbApSthqvngXU1M2y5XvdcTTFv4I9ts60UWkhaDuuXA
Verifying a JWT Signature
In this example, I am only going to validate the JWT’s signature.
I’ll do this using the verify method on SignedJWT
.
val isValid: Boolean = SignedJWT.parse(jwt)
.verify(ECDSAVerifier(key.toECPublicKey()))
JWTs Signed using EdDSA
Using EdDSA in Nimbus JOSE + JWT is much the same as the above, but we’ll need to use a different curve (Ed25519), generate our key as an OctetKeyPair
, and install Google’s Tink package:
implementation "com.google.crypto.tink:tink:1.2.2"
My implementation ended up looking like this:
// generate key
val key: OctetKeyPair = OctetKeyPairGenerator(Curve.Ed25519)
.keyID("123")
.generate()
// generate signed JWT
val header = JWSHeader.Builder(JWSAlgorithm.EdDSA)
.type(JOSEObjectType.JWT)
.keyID(key.keyID)
.build();
val payload = JWTClaimsSet.Builder()
.issuer("me")
.audience("you")
.subject("bob")
.expirationTime(Date.from(Instant.now().plusSeconds(120)))
.build()
val signedJWT = SignedJWT(header, payload)
signedJWT.sign(Ed25519Signer(key))
val jwt: String = signedJWT.serialize()
// validate signature (and only signature)
val isValid: Boolean = SignedJWT.parse(jwt)
.verify(Ed25519Verifier(key.toPublicJWK()))
Example JWT Signed Using EdDSA
eyJraWQiOiIxMjMiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJhdWQiOiJ5b3UiLCJzdWIiOiJib2IiLCJpc3MiOiJtZSIsImV4cCI6MTU3NTEyOTEyNH0.vTRyDo4R6cmeI1cfnUznyZBabQAb_IQOCrg4aq4--G-tJACNgvRn4a9gUIB4fShVlz5-LMtHvpV6ZP_faeLMAA
Source Code
You can find code samples for both ES256K and EdDSA on GitHub. You’re welcome future Scott.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK