jwtk/jjwt

Unable to verify Elliptic Curve signature using configured ECPublicKey. Invalid encoding for signature

StefHoeben opened this issue · 2 comments

Looks like there is a bug in 0.9.x:

in EllipticCurveSignatureValidator.isValid():

            ...
            int expectedSize = EllipticCurveSignatureValidator.getSignatureByteArrayLength(this.alg);
            byte[] derSignature = expectedSize != signature.length && signature[0] == 48 ? signature : EllipticCurveProvider.transcodeSignatureToDER(signature);

The problem is that getSignatureByteArrayLength() returns a fixed length depending on the hash algo instead of the signature algo; so if you use a 384 bit key but a sha256 hash it will return 64 instead of 196. And then if signature[0] is accidentally 0x30 = 48 (next line) it assumes the signature is DER encoded and tries to parse it -> error.

So the bug can occur (about 1 time in 256) for EC signature when the key size differs from the hash size.

Little correction: "instead of the signature algo" should be "instead of the key size"

Example: this is the hex dump of a signature made with ES256 but with a P384 key (and the accidentally starts with 0x30):
3065023030749319BAC407F23AF6AE58744B3856424A145DB96008E9B75DA96FCF93E570583F38CE860F80A6B238C2BD22289B8D023100E2CF7A8A336412D50511D583276392E71FF91B7BB0D1B3BC03A90E2C04DE9772BB00195A13C4E63339921D34C242E7FD

Hi @StefHoeben!

0.9.x is 6 years old and no longer supported.

If you're able, please upgrade to the latest stable JJWT release (0.12.5 at the time of writing). 0.12.x is a bigger API leap than most releases (please read the Changelog!), and this may require a number of changes to your application code, but the upgrade may not be difficult depending on how much JJWT customization you've made.

If you're unable to do this now, 0.11.5 has a change that only performs the DER check if a system property has been set instructing JJWT to assume DER. Otherwise it assumes the JWT RFC-standard IEEE P1363 format as you'd expect.

I'm closing this because the fix is already in 0.11.5 and 0.12.x, but feel free to comment below if those don't work. Thanks!