# Java JOSE Proposal ## Proposed Option Implement required JOSE parts in Java based on **nimbus-jose-jwt** (https://bitbucket.org/connect2id/nimbus-jose-jwt). nimbus-jose-jwt lacks only the following features that we need: - ECDH-1PU key agreement scheme, - XC20P encryption algorithm, - JSON serialization for JWS and JWE and multi-recipient support. The plan is to make a fork, implement the lacked features in it and contribute to upstream. An issue ticket with this proposal has been created: https://bitbucket.org/connect2id/nimbus-jose-jwt/issues/439/interested-in-a-meaningful-contribution ## All Options 1. Fork nimbus-jose-jwt, implement the lacked features in it and contribute to upstream. *(In case contribution is not accepted for some reasons, switch to Option 2 or Option 3.)* * Pros: * Natural separation between DIDComm and JOSE parts * No need to maintain a fork. * Cons: * None. 2. Implement the lacked features not in nimbus-jose-jwt but in DIDComm Java library itself which will depend on nimbus-jose-jwt upstream. * Pros: * No contribution to nimbus-jose-jwt upstream is needed. * No need to maintain a fork. * Cons: * DIDComm and JOSE parts are messed over libraries. 3. Copy the necessary JOSE part from nimbus-jose-jwt right into DIDComm library and implement the lacked features within DIDComm library too. * Pros: * No contribution to nimbus-jose-jwt upstream is needed. * No need to maintain a fork. * Cons: * Having both DIDComm and JOSE parts in the same library. 4. Fork nimbus-jose-jwt, implement the lacked features in it and use the fork as a dependency in DIDComm Java library. * Pros: * Natural separation between DIDComm and JOSE parts in any case. * No contribution to nimbus-jose-jwt upstream is needed. * Cons: * Necessity to maintain the fork and regularly merge with upstream's master. 5. Implement a common JOSE library in Rust and provide a Java wrapper around it. * Pros: * Only one JOSE library to maintain and fix. * Cons: * More difficult for community to maintain DIDComm library. * Needs a wrapper per each language. * More dependencies for DIDComm libraries. # Libraries Comparison The following open-source Java JOSE libraries have been considered: * [java-jwt](https://github.com/auth0/java-jwt) * [jose4j](https://bitbucket.org/b_c/jose4j) * [nimbus-jose-jwt](https://bitbucket.org/connect2id/nimbus-jose-jwt) * [jjwt](https://github.com/jwtk/jjwt) * [fusionauth-jwt](https://github.com/fusionauth/fusionauth-jwt) * [vertx-auth-jwt](https://github.com/vert-x3/vertx-auth/tree/master/vertx-auth-jwt) ## Supported JOSE specs * [RFC7515: JSON Web Signature](https://datatracker.ietf.org/doc/html/RFC7515) * [RFC7516: JSON Web Encryption](https://datatracker.ietf.org/doc/html/RFC7516) * [RFC7517: JSON Web Key](https://datatracker.ietf.org/doc/html/RFC7517) * [RFC7518: JSON Web Algorithms](https://datatracker.ietf.org/doc/html/rfc7518) * [RFC7519: JSON Web Token](https://datatracker.ietf.org/doc/html/RFC7519) * ECDH-ES * ECDH-1PU | Library | JWS | JWE | JWK | JWA | JWT | ECDH-ES | ECDH-1PU | | --------------- | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | | java-jwt | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | N/A | N/A | | jose4j | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | | nimbus-jose-jwt | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | | jjwt | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | N/A | N/A | | fusionauth-jwt | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | N/A | N/A | | vertx-auth-jwt | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | N/A | N/A | **NOTES:** - **nimbus-jose-jwt** mentions ECDH-1PU on roadmap. - **jjwt** mentions JSON serialization and JWE support in future release plans. - **vertx-auth-jwt** is a submodule of **vertx-auth** module intended for authentication and authorization support. ## Supported JWS/JWE Serialization | Library | JWS Compact Serialization | JWS JSON Serialization | JWE Compact Serialization | JWE JSON Serialization | | --------------- | ------------------------- | ---------------------- | ------------------------- | ---------------------- | | java-jwt | :heavy_check_mark: | :x: | N/A | N/A | | jose4j | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | | nimbus-jose-jwt | :heavy_check_mark: | :x: | :heavy_check_mark: | :x: | | jjwt | :heavy_check_mark: | :x: | N/A | N/A | | fusionauth-jwt | :heavy_check_mark: | :x: | N/A | N/A | | vertx-auth-jwt | :heavy_check_mark: | :x: | N/A | N/A | ## Supported Curves | Library | X25519 | P-384 | P-256 | | --------------- | ------------------ | ------------------ | ------------------ | | java-jwt | :x: | :heavy_check_mark: | :heavy_check_mark: | | jose4j | :x: | :heavy_check_mark: | :heavy_check_mark: | | nimbus-jose-jwt | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | jjwt | :x: | :heavy_check_mark: | :heavy_check_mark: | | fusionauth-jwt | :x: | :heavy_check_mark: | :heavy_check_mark: | | vertx-auth-jwt | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | ## Supported Signature Protocols | Library | EdDSA (with crv=Ed25519) | ES256 | ES256K | | --------------- | ------------------------ | ------------------ | ------------------ | | java-jwt | :x: | :heavy_check_mark: | :heavy_check_mark: | | jose4j | :x: | :heavy_check_mark: | :x: | | nimbus-jose-jwt | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | jjwt | :x: | :heavy_check_mark: | :x: | | fusionauth-jwt | :x: | :heavy_check_mark: | :x: | | vertx-auth-jwt | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | ## Supported Encryption Protocols | Library | XC20P | A256GCM | A256CBC-HS512 | | --------------- | ------------------ | ------------------ | ------------------ | | java-jwt | N/A | N/A | N/A | | jose4j | :x: | :heavy_check_mark: | :heavy_check_mark: | | nimbus-jose-jwt | :x: | :heavy_check_mark: | :heavy_check_mark: | | jjwt | N/A | N/A | N/A | | fusionauth-jwt | N/A | N/A | N/A | | vertx-auth-jwt | N/A | N/A | N/A | ## Supported Key Wrapping Algorithms | Library | ECDH-ES+A256KW | | --------------- | ------------------ | | java-jwt | N/A | | jose4j | :heavy_check_mark: | | nimbus-jose-jwt | :heavy_check_mark: | | jjwt | N/A | | fusionauth-jwt | N/A | | vertx-auth-jwt | N/A | ## License | Library | License | | --------------- | ------------------ | | java-jwt | MIT | | jose4j | Apache 2.0 | | nimbus-jose-jwt | Apache 2.0 | | jjwt | Apache 2.0 | | fusionauth-jwt | Apache 2.0 | | vertx-auth-jwt | Apache 2.0 | ## External Contributions ### java-jwt If anyone has found a bug or has a feature request, it is suggested to create an issue ticket. If maintainers agree on the ticket, the user may raise a pull request with tests which all must pass. The pull request author must follow the general contribution guidelines and the code of conduct of Auth0 organization on GitHub. ### jose4j Nothing is explicitly said about user contributions policy. But from the pull requests history it looks like that they accept some contributions from users. ### nimbus-jose-jwt Open for external contributions. Bug reports and pull requests (preferably with tests) from users are appreciated. ### jjwt Open for external contributions. An issue ticket should be created if a user is going to make changes in the core code. If maintainers agree on the ticket, the user may raise a pull request. ### fusionauth-jwt Nothing is explicitly said about user contributions policy. But from the pull requests history it looks like that they accept some contributions from users. ### vertx-auth-jwt In the containing repository itself (https://github.com/vert-x3/vertx-auth) there is nothing explicitly said about user contributions policy. However, in merged pull requests there are references to Eclipse Vert.x community contributing guide (https://github.com/eclipse/vert.x/blob/master/CONTRIBUTING.md) and to Vert.x code style guidelines (https://github.com/vert-x3/wiki/wiki/Vert.x-code-style-guidelines). According to Eclipse Vert.x community contributing guide, contributions are encouraged. ## How ECDH-1PU Can Be Supported ### nimbus-jose-jwt ECDH-1PU is on the roadmap of future development. If it is needed earlier, we can implement it in the fork and raise a pull request to upstream. ## Base Crypto Library | JOSE Library | Base Crypto Library | | --------------- | ----------------------------------------------------------------------- | | java-jwt | JCA providers (Java built-in or 3rd party) | | jose4j | JCA providers (Java built-in or 3rd party) | | nimbus-jose-jwt | JCA providers (Java built-in or 3rd party), Tink for Ed25519 and X25519 | | jjwt | JCA providers (Java built-in or 3rd party) | | fusionauth-jwt | JCA providers (Java built-in or 3rd party) | | vertx-auth-jwt | JCA providers (Java built-in or 3rd party) | ## Supported Platforms | Library | Supported Platforms | | --------------- | ------------------- | | java-jwt | Java 8+ | | jose4j | Java 7+ | | nimbus-jose-jwt | Java 7+ | | jjwt | Java 7+, Android | | fusionauth-jwt | Java 8+ | | vertx-auth-jwt | Java 8+ | ## Known Security Issues ## Popularity ### java-jwt ~4300 stars and ~800 forks on GitHub. ~250 issue tickets (2 open). The project is in an active development phase. ### jose4j 48 forks on Bitbucket. ~200 issue tickets (~20 open). Only 1 pull request was merged during the last 12 months. ### nimbus-jose-jwt 89 forks on Bitbucket. ~400 issue tickets (~40 open). The project is in an active development phase. ### jjwt ~7600 stars and ~1100 forks on GitHub. ~450 issue tickets (~50 open). The project is in an active development phase. ### fusionauth-jwt 66 stars and 34 forks on GitHub. 22 issue tickets (5 open). The project was in an active development phase in 2nd half of 2020 but no pull requests have been merged and only a few commits have been done in 2021 so far. ### vertx-auth-jwt The parent module **vertx-auth** has ~130 starts and ~130 forks on GitHub. **vertx-auth** has ~250 issue tickets (~20 open). The project is in an active development phase. # Conclusion According to the comparison results, **nimbus-jose-jwt** (https://bitbucket.org/connect2id/nimbus-jose-jwt) looks the most suitable for our needs. It allows to use any payload/plaintext type conforming JWS/JWE specifications, not only a claim set (which is used as the payload/plaintext when JWS/JWE instance is a JWT) as some other JOSE libraries allow only. nimbus-jose-jwt relies on JRE built-in JCA providers and optionally on Bouncy Castle or Bouncy Castle FIPS JCA provider. Android has a different list of built-in JCA providers than JRE has but there is a solution from nimbus-jose-jwt maintainers how possible issues with lack of necessary crypto algorithms or curves on Android can be solved: https://connect2id.com/products/nimbus-jose-jwt/jca-algorithm-support#bc-android nimbus-jose-jwt lacks only the following features that we need: - ECDH-1PU key agreement scheme, - XC20P encryption algorithm, - JSON serialization for JWS and JWE and multi-recipient support. We propose to make a fork, implement the lacked features in it and raise a pull request to upstream. If nimbus-jose-jwt maintainers accept it before DIDComm release, we will use nimbus-jose-jwt upstream as a dependency. Otherwise we will just copy the code from the fork right into DIDComm Java library in order not to have a dependency on the fork and hence a necessity to maintain it and regularly merge with upstream's master. **WBS of nimbus-jose-jwt modifications:** - Implement ECDH-1PU key agreement scheme. - Add XC20P encryption algorithm. - Implement JSON serialization for JWS and JWE and multi-recipient support. **NOTES:** - ECDH-1PU is on the roadmap of nimbus-jose-jwt future development. If it is added to the library before DIDComm library release, we will just use it. Otherwise we will use our implementation of ECDH-1PU added to nimbus-jose-jwt. - XChaCha20Poly1305 (XC20P) is supported by Google Tink 1.5.0 which is used by the current nimbus-jose-jwt version (as well as supported by the latest Google Tink version, 1.6.1). So adding this feature to nimbus-jose-jwt will be rather trivial.