Cannot sign JWS with BCFIPS and PS256 algorithm

Create issue
Issue #403 resolved
Ori Doolman created an issue

Hi,
I want to use Bouncy Castle FIPS version as a provider (bc-fips:1.0.2), with algorithm PS256, and I get a NoSuchAlgorithmException.

The problem is that in RSSSA#getSignerAndVerifier, the resulting algorithm name is "RSASSA-PSS".
While this is working well with the regular BC provider, it doesn't work with the FIPS version (bc-fips:1.0.2), which expects it to be "SHA256withRSAandMGF1".
See here for example:
https://downloads.bouncycastle.org/fips-java/BC-FJA-UserGuide-1.0.2.pdf
under Example 30.

This can be easily reproduced by:

    JWSSigner signer = new RSASSASigner(privateKey);
    signer.getJCAContext().setProvider(new BouncyCastleFipsProvider());
    JWSObject jwsObject = new JWSObject(
            new JWSHeader.Builder("PS256").keyID(UUID.randomUUID().toString()).type(JOSEObjectType.JWT).build(),
            new Payload("some payload"));
    jwsObject.sign(signer);

I wonder if that is a bug in Nimbus or in the bcfips library which is not consistent to the regular version.
In any case, can you add the ability to use the bcfips version by allowing an additional input flag isFips or the ability to override the algorithm name or any other method?

Regards,
Ori.

Comments (6)

  1. Ori Doolman reporter

    Hi @Vladimir Dzhuvinov ,

    That sounds like a very good enhancement.

    Do you have any estimation when this change can be available? Is there any issue I can track besides this one?

    Thanks,

    Ori.

  2. Vladimir Dzhuvinov

    On 9.x ca0d29d , released as v9.6.

    On 8.x 2d4f2e3 , released as v8.21.

    The snippet you posted should now work, with no code changes.

    Also, consider using the BC singleton helper, to prevent accidental memory leaks.

  3. Ori Doolman reporter

    @Vladimir Dzhuvinov , thanks for the quick fix.

    I reviewed the code and I have a suggestion for a different approach. I added comments, but I bring it here as well.

    I suggest a different fix, because:

    1. If I’m not setting a specific Provider, the behavior is depending on the order of providers in the JVM. If there’s a high-priority provider that matches “RSASSA-PSS“ , it will never reach the alt.
    2. When using BCFIPS, it means that there will always be an exception, and only then ‘jcaAlgAlt’ will take effect. Having a code that throws exception by design is not the best approach IMO.

    The solution I suggest:

    Provide an additional interface RsaSsaAlgorithmNameResolver as a new member that would serve as the name resolver. It will have a DefaultRsaSsaAlgorithmNameResolver implementation with the same names as today, and also a BCFIPSRsaSsaAlgorithmNameResolver implementation (the alternative).

    Also, it would be possible override it by setting the resolver. Specifically, RSASSAVerifier and RSASSASigner would set it when creating RSASSA .

    As a user I will be able to do myRSASSASigner.setAlgorithmNameResolver(..).

    Also , I should be able to somehow set the algorithm name resolver in DefaultJWSVerifierFactory which is needed to the case where Spring Security is used.

    Today, my code looks like this:

            jwtDecoder = NimbusJwtDecoder.withPublicKey(key).signatureAlgorithm(SignatureAlgorithm.from(jwsAlgorithm))
                    .jwtProcessorCustomizer(p -> p.setJWSVerifierFactory(new FipsJWSVerifierFactory()))
                    .build();
    

    (FipsJWSVerifierFactoryis my private implementation of DefaultJWSVerifierFactory , where the only difference is the way RSASSAVerifier is initialized)

  4. Log in to comment