equalTo/hashCode for JsonWebKey

Issue #166 wontfix
Dirk Bolte created an issue

I just stumbled upon an issue that I have to compare JsonWebKeys. Unfortunately, as there is no equalTo, the comparison is solely based on the object identifier.

Example. I would expect the following (Kotlin) code to work:

import org.assertj.core.api.Assertions
import org.jose4j.jwk.JsonWebKey
import org.junit.jupiter.api.Test
import java.security.KeyPairGenerator
import java.util.UUID

class SimpleTest : AbstractDtoTest() {

    @Test
    fun keyEqualsTest() {
        val kpg = KeyPairGenerator.getInstance("RSA")
        kpg.initialize(512)
        val public = kpg.genKeyPair().public
        val key = JsonWebKey.Factory.newJwk(public)
        key.keyId = UUID.randomUUID().toString()

        val jsonKey = key.toJson()

        Assertions.assertThat(JsonWebKey.Factory.newJwk(jsonKey)).isEqualTo(JsonWebKey.Factory.newJwk(jsonKey))
    }
}

I would expect that keys are equal based on their parameters. Is there a specific reason why this is not implemented? Otherwise, would it be ok for me to open a PR for this?

Comments (4)

  1. Brian Campbell repo owner

    Yeah, the reason it’s not implemented is that the meaning of equality for a JWK is rather fuzzy and context dependent. Would the same actual key with and without a kid be the same? What about with/without x5t? RFC7638 sort of defines things in the context of fingerprinting a key but mostly in the context of some other party consuming the fingerprint in some other context like in a token. But a RFC7638 thumbprint would be the same for a pair of otherwise identical JWKs but where one had private key info and the other did not. It just depends. And so I’ve not tried to pick one way and left any such comparison up to the application to do in the way that their context would dictate.

  2. Dirk Bolte reporter

    Hmm, as this is a JSON web key, it should define as equal whatever is equal on JSON level, and that should be (although I haven’t found a sound definition thereof): same keys, same values. In the end, JsonWebKey is just an object representation of an object notation, thus itIt shouldn’t be the key that is driving equality but the object notation.

    So:

    • if kid is different: not equal
    • if x5c is missing: not equal
    • if the resulting JSON is equal: equal
    • generated from the same JSON: equal

    Maybe I’m having a simplified perspective, but when converting an object to a different representation and back, I would expect equal to succeed. It’s one test I do for every DTO in a REST API or a database. Unfortunately, for this object I have to write extra code to match that expectation. For Comparable, it would be a completely different discussion though 🙂

    As said I would be happy to provide a PR for this.

  3. Brian Campbell

    Sorry, those questions were meant to be rhetorical. I was tying to use the questions to help illustrate why expectations about JWK comparison/equality are dependent on context. And, as such, the library doesn't do anything with equals/hashcode and the JsonWebKey classes and leaves any such comparison up to the application to do in the way that their context would dictate.

  4. Log in to comment