This is the Kotlin implementation of the basic JWT methods for DID-JWTs
The kotlin-did-JWT library allows you to sign and verify JSON Web Tokens (JWT) using ES256K, and ES256K-R algorithms.
Public keys are resolved using the
Decentralized ID (DID)
of the signing identity of the claim, which is passed as the iss
attribute of the encoded JWT.
We currently support the following DID methods:
Defaults are automatically installed but you can customize to fit your needs.
Support for other DID methods should be simple.
Write a DID resolver supporting the
DIDResolver
interface.
Install it using
val resolver : DIDResolver = DIDResolver.Builder
.addResolver(ethrDidResolver)
.addResolver(/*...*/)
.build()
Once you've verified that it works, feel free to advertise it in the list above so people can find it.
If your DID method requires a different signing algorithm than what is already supported, please create a PR.
The libraries built here are distributed through jitpack
In your main build.gradle
file, add:
allprojects {
repositories {
maven { url 'https://jitpack.io' }
//...
}
}
In your application build.gradle
file, add:
def did_jwt_version = "0.4.0"
dependencies {
//...
implementation "com.github.uport-project.kotlin-did-jwt:jwt:$did_jwt_version"
}
In practice you should secure the key passed to KPSigner. The key provided in code below is for informational purposes.
val jwt = JWTTools()
//...
val payload = mapOf(
"claims" to mapOf("name" to "R Daneel Olivaw")
)
val signer = KPSigner("0x54ece214d38fe6b46110a21c69fd55230f09688bf85b95fc7c1e4e160441ece1")
val issuerDID = "did:ethr:${signer.getAddress()}"
val token = jwt.createJWT(payload, issuerDID, signer)
Try decoding the JWT. You can also do this using jwt.io
val (header, payload, sig) = jwt.decodeRaw("eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NkstUiJ9.eyJjbGFpbXMiOnsibmFtZSI6IlIgRGFuZWVsIE9saXZhdyJ9LCJpYXQiOjEyMzQ1Njc4LCJleHAiOjEyMzQ1OTc4LCJpc3MiOiJkaWQ6ZXRocjoweDQxMjNjYmQxNDNiNTVjMDZlNDUxZmYyNTNhZjA5Mjg2YjY4N2E5NTAifQ.o6eDKYjHJnak1ylkpe9g8krxvK9UEhKf-1T0EYhH8pGyb8MjOEepRJi8DYlVEnZno0DkVYXQCf3u1i_HThBKtAA")
The decoded payload resembles:
mapOf(
"claims" to mapOf("name" to "R Daneel Olivaw"),
"iat" to 1.2345678E7,
"exp" to 1.2345978E7,
"iss" to "did:ethr:0x4123cbd143b55c06e451ff253af09286b687a950"
)
You can also use jwt.decode("<token>")
to get a JwtPayload
object instead of a map
but that is a more rigid structure and will be phased away in future releases.
val resolver = EthrDIDResolver.Builder()
.addNetwork(EthrDIDNetwork("<name>", "<registryAddress>", "<JsonRPC>"))
.build()
val payload : JwtPayload = JWTTools().verify("<token>", resolver)
If the token is valid, the method returns the decoded payload,
otherwise throws a InvalidJWTException
or JWTEncodingException
This behavior is subject to change in an upcoming release The verify() method will return a higher level abstraction that will contain the payload and more.
The function requires a DIDResolver which will be used to resolve DIDs during the verification
Verifying a token means checking that the signature was produced by a
key associated with the issuer DID (iss
field).
This association is resolved by a DID resolver, which can produce a DIDDocument
listing various public keys and service endpoints for a given DID.
If the token contains a non null aud
field, an additional soft-check is performed to
match the verification against an intended audience.
This same aud
DID must be supplied to the verify()
method for the token to be marked as valid
(after passing all the cryptographic checks as well).
Generally your app will have its own DID which should always be passed to the verify
method
so that only tokens intended for your app are considered valid.
iat
field when creating JWTs (#17)https-did
module, now replaced by web-did
(#14)@Serializer
s as JWT payloads (#16)jwt-test
module with helpers for testing