bob
bob

Reputation: 2734

Can I use latest BouncyCastle provider on Android?

I am writing the app for Android 1.6.
Can anyone tell me if it is possible to use latest Bouncy Castle provider (version 1.46) instead of old one contained in SDK?
If so, correct instructions will be appreciated.

Upvotes: 7

Views: 9039

Answers (3)

k_o_
k_o_

Reputation: 6298

In the meanwhile Android has changed the package name and BC can be used in its latest version. But there is still at least one problem:

The provider name "BC" is taken by the old built-in BC version. Adding BC with Security.addProvider(new BouncyCastleProvider(), 0) as first provider might work in simple cases, but Android Pie introduced a nasty check for the BouncyCastleProvider not allowing several modes, e.g. the X.509 certificate path checking cannot be instantiated and some other algorithms. This problem occurs when BC is added with Security.addProvider before sun.security.jca.Providers is first touched. Adding BC to the list of providers is usually required to be able to route indirect calls from other code referring the BC to the new BC version. E.g. the PKCS12 key store is using in its code a call to build a CertificateFactory using BC.

The check is in sun.security.jca.Providers and called e.g. from java.security.cert.CertificateFactory. The code cannot differentiate between Android's included BC version and a newer working version. The hack to overcome this problem is to execute this piece of code early when the app is starting. The code must be executed before sun.security.jca.Providers is touched, otherwise a static code fragment is already executed reading in the existing crypto providers:

private static final String SUN_PROVIDERS = "sun.security.jca.Providers";

...
    // remove BC provider first
    Security.removeProvider("BC");
    // also remove not sufficient AndroidOpenSSL provider for X.509 - most likely only needed if BouncyCastleJsseProvider is used
    Security.removeProvider("AndroidOpenSSL");
    // touch the internal Providers class to trigger the static provider loading
    // see http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/sun/security/jca/Providers.java#SYSTEM_BOUNCY_CASTLE_PROVIDER
    try {
        Class.forName(SUN_PROVIDERS);
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(String.format("%s to patch not found.", SUN_PROVIDERS), e);
    }
    // insert modern BC as first crypto provider
    Security.insertProviderAt(new BouncyCastleProvider(), 0);

Upvotes: 7

bob
bob

Reputation: 2734

Found the issue on google and SpongyCastle. After I added jar and called addProvider(), the app became bigger but could use BC 1.46 features like "Whirlpool" digest.

...the Android platform unfortunately incorporates a cut-down version of Bouncy Castle, which also makes installing an updated version of the libraries difficult due to classloader conflicts.

If you really need the full version of the Bouncy Castle libraries in your Android app, you may find it convenient to use Spongy Castle - a repackage of Bouncy Castle for Android:

Upvotes: 13

President James K. Polk
President James K. Polk

Reputation: 42009

You should be able to at least use the lightweight crypto library. Look for the lcrypto-jdk* on the releases page. I confess I don't have a android test environment available to verify any of this. Note that this version of the library does not use the JCE API.

Upvotes: 0

Related Questions