justinludwig / jpgpj

Java Pretty Good Privacy Jig
MIT License
75 stars 20 forks source link

Support for bc-fips #36

Closed smirandamedallia closed 3 years ago

smirandamedallia commented 3 years ago

Hello Team - Is there a way to use this jar in fips mode ? Following is what I currently have working in my gradle project but am unsure if this is the correct way to do it.

    implementation('org.c02e.jpgpj:jpgpj:1.1')     
    implementation('org.bouncycastle:bc-fips:1.0.2.1')
    implementation('org.bouncycastle:bcpg-fips:1.0.5.1')
Security.addProvider(new BouncyCastleFipsProvider());

// I had to add this else the initialization fails
CryptoServicesRegistrar.setSecureRandom(
                FipsDRBG.SHA512_HMAC.fromEntropySource(
                        new BasicEntropySourceProvider(
                                new SecureRandom(), true))
                        .build(null, false)
        );

I took a look at some of the classes being used like PGPSignatureGenerator and there look to be two implementations of it, one from bcpg-fips and another from bcpg-jdk15on which looks confusing. I tried doing this in my build.gradle

implementation('org.c02e.jpgpj:jpgpj:1.1') {
        exclude group: 'org.bouncycastle', module: 'bcpg-jdk15on'
    }

But it fails with the following

Exception in thread "main" java.lang.NoClassDefFoundError: org/bouncycastle/openpgp/bc/BcPGPObjectFactory
    at org.c02e.jpgpj.Ring.parse(Ring.java:301)
    at org.c02e.jpgpj.Ring.load(Ring.java:273)
    at org.c02e.jpgpj.Ring.load(Ring.java:260)
    at App.readKeyRingUsingJPGPJ(App.java:35)
    at App.main(App.java:26)
Caused by: java.lang.ClassNotFoundException: org.bouncycastle.openpgp.bc.BcPGPObjectFactory
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    ... 5 more

I would really love some help in figuring out what would be the best way to use this library in fips mode

justinludwig commented 3 years ago

Thanks for raising this issue! I don't think it's currently possible to use the BC FIPS jars with JPGPJ -- JPGPJ is hardcoded in a number of places to use the default (non-FIPS) BC implementation of various crypto primitives. JPGPJ would have to be refactored a bit to lookup the implementation of those primitives through JCA (which would then allow you to configure it to use the FIPS JCA provider).

smirandamedallia commented 3 years ago

Thanks for the quick response

justinludwig commented 3 years ago

With @smirandamedallia's fix for this from #39, it's now possible to swap in the Bouncy Castle FIPS implementation -- add the following to your build.gradle file:

implementation 'org.bouncycastle:bcpg-fips:1.0.5.1'
implementation('org.c02e.jpgpj:jpgpj:1.2') {
    exclude group: 'org.bouncycastle', module: 'bcpg-jdk15on'
}

And then set the securityProvider property of JPGPJ's new JcaContextHelper class to use the Bouncy Castle FIPS JCA provider in your application's initialization code (before using any JPGPJ functionality):

import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import org.c02e.jpgpj.JcaContextHelper;

...

JcaContextHelper.setSecurityProvider(new BouncyCastleFipsProvider());