Add Ed25519 support via Java JCA (when it becomes available)

Issue #338 new
Michael Barnwell created an issue

BouncyCastle 1.61+ support Ed25519 naively, this allows us to choose between Google Tink and BouncyCastle - since BouncyCastle supports using Ed25519 through JCA, I think it’s a better approach.

I’ve taken a stab at the change at https://bitbucket.org/MPBarnwell/nimbus-jose-jwt (which I attempted to create a pull request from but I seem to need additional permissions).

This change removes Google Tink (except for tests), adds support for EdDSA in the DefaultJWSVerifierFactory, adds the Ed* OIDs defined in RFC8410 and fixes a memory leak in IOUtils that was making a test fail for me.

There are probably still a few changes that should be made, but I wanted some feedback before I got carried away - in particular, it should be easy to add support for EdDSA in the JWKMatcher (issue #323) and it should also be possible to support Ed25519 on X509Certificate (issue #281) but the certificate seemingly needs to be generated/loaded using BouncyCastle as the CertificateFactory provider or an exception is thrown.

Comments (3)

  1. Yavor Vasilev

    Hi Michael,

    This looks interesting.

    I wasn’t aware that BC implemented Ed25519 via JCA and that JCA supports that (officially).

    We’d like to keep the Tink since we have people relying on it and it was tested for performance. The integration was also audited.

    Would you be interested in making the changes as an alternative Ed25519 signer / verifier? E.g. Ed25519JCASigner / Verifier.

    The JWK classes would ideally be independent from third party libs and rely on JCA classes only. Do you think this can be done for the OKP JWK?

  2. Yavor Vasilev

    I have the feeling that BC have created their own JCA API for EdDSA, because officially the JCA spec for EdDSA is still work in progress:

    https://bugs.openjdk.java.net/browse/JDK-8190219

    https://openjdk.java.net/jeps/339

    E.g. signer is created with a different name:

    // example: generate a key pair and sign
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519");
    KeyPair kp = kpg.generateKeyPair();
    // algorithm is pure Ed25519
    Signature sig = Signature.getInstance("Ed25519");
    sig.initSign(kp.getPrivate());
    sig.update(msg);
    byte[] s = sig.sign();
    
    // example: use KeyFactory to contruct a public key
    KeyFactory kf = KeyFactory.getInstance("EdDSA");
    boolean xOdd = ...
    BigInteger y = ...
    NamedParameterSpec paramSpec = new NamedParameterSpec("Ed25519");
    EdECPublicKeySpec pubSpec = new EdECPublicKeySpec(paramSpec, new EdPoint(xOdd, y));
    PublicKey pubKey = kf.generatePublic(pubSpec);
    

  3. Log in to comment