rtyley / spongycastle

Spongy Castle - a repackage of Bouncy Castle for Android (which ships a crippled version of BC)
https://rtyley.github.io/spongycastle/
MIT License
684 stars 141 forks source link

JCE Provider Addition #27

Open hf opened 8 years ago

hf commented 8 years ago

This is not really a bug, but is a problem in the way that the website for SpongyCastle advises users to add the JCE provider.

Currently, the website advertises:

Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1);

As the method to use SpongyCastle.

Please change it to:

Security.addProvider(new org.spongycastle.jce.provider.BouncyCastleProvider());

The advertised method creates issues by using the Android Key Store on API 18 and up, and sometimes creates issues with the Fingerprint APIs on some devices on API 23 and up.

Also, please inform the user on explicitly using the "SC" provider for all SpongyCastle cryptographic operations, instead of relying on the provider ordering and resolution.

rtyley commented 8 years ago

Thanks for reporting this @hf. The docs were updated to use insertProviderAt() back in 2013 to address https://github.com/rtyley/spongycastle-old/issues/10 reported by @stubb.

Although it's convenient to some users to have SpongyCastle attempt to take over all JCE operations (especially when they're using 3rd party libraries that blindly call JCE functions without allowing specification of the provider), I agree that in general it's probably safest to activate SpongyCastle explicitly with the "SC" provider argument.

The advertised method creates issues by using the Android Key Store on API 18 and up,
and sometimes creates issues with the Fingerprint APIs on some devices on API 23 and up.

I can guess that might be the case, but could you provide a quick explanation, or links to references, of what the issues are?

hf commented 8 years ago

If you want to use the AndroidKeyStore mechanism to use device-secured keys (self-signed RSA certificates) then the certificate generation, as documented, fails at least on Android 4.4.2 with SpongyCastle specific exceptions.

I'm guessing that in the background, the AndroidKeyStore KeyPairGenerator uses an internal RSA KeyPairGenerator. Instead of using AndroidOpenSSL or some other (device specific) provider, it resolves the SpongyCastle provider and it's RSA KeyPairGenerator. Then, when the AndroidKeyStore tries to securely store the private exponent of the RSA key, SpongyCastle's private key implementation throws an exception.

Here is a snippet of the exception on Android 4.4.2.

Caused by: java.lang.UnsupportedOperationException: private exponent cannot be extracted
at com.android.org.conscrypt.OpenSSLRSAPrivateKey.getPrivateExponent(OpenSSLRSAPrivateKey.java:143)
at org.spongycastle.jcajce.provider.asymmetric.rsa.RSAUtil.generatePrivateKeyParameter(SourceFile:63)
at org.spongycastle.jcajce.provider.asymmetric.rsa.DigestSignatureSpi.engineInitSign(SourceFile:95)
at java.security.Signature$SignatureImpl.engineInitSign(Signature.java:631)
at java.security.Signature.initSign(Signature.java:280)
at com.android.org.bouncycastle.x509.X509Util.calculateSignature(X509Util.java:257)
at com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(X509V3CertificateGenerator.java:434)
at com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(X509V3CertificateGenerator.java:412)
at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:134)
at java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:275) 

Again, this is not a bug in SpongyCastle, but rather in the AndroidKeyStore implementations. The problem can be solved as described in the initial report.

Something similar also happens when using the Fingerprint API, but the problems there can be alleviated if you specify the undocumented Android JCE providers for the fingerprinting.

The issue https://github.com/rtyley/spongycastle-old/issues/10 is also not a bug in SpongyCastle, but improper use of the JCE provider architecture. This is why I'm suggesting that people must explicitly use the SC provider by name, if they require SpongyCastle-specific algorithms. I think this should be noted on the website.

This is a very big problem since third-party libraries that use SpongyCastle internally use it as specified, and the problem is not able to be overcome unless the library changes the insert position.