patrickfav / armadillo

A shared preference implementation for confidential data in Android. Per default uses AES-GCM, BCrypt and HKDF as cryptographic primitives. Uses the concept of device fingerprinting combined with optional user provided passwords and strong password hashes.
https://favr.dev/opensource/armadillo
Apache License 2.0
280 stars 52 forks source link

Library could not encrypt error on Android 9.0 with "BC" security provider #43

Closed seperot closed 5 years ago

seperot commented 5 years ago

When running the following code to encrypt our SharedPreferences:

return Armadillo.create(context, prefsName) .encryptionFingerprint(context) .securityProvider(Security.getProvider("BC")) .keyStretchingFunction(new PBKDF2KeyStretcher()) .enableKitKatSupport(true) .build();

I get the following issues on Android 9.0+

Caused by: java.lang.IllegalStateException: at.favre.lib.armadillo.EncryptionProtocolException: at.favre.lib.armadillo.AuthenticatedEncryptionException: could not encrypt at at.favre.lib.armadillo.SecureSharedPreferences.encryptToBase64(SecureSharedPreferences.java:511) at at.favre.lib.armadillo.SecureSharedPreferences.access$400(SecureSharedPreferences.java:33) at at.favre.lib.armadillo.SecureSharedPreferences$Editor.putString(SecureSharedPreferences.java:412)

I know Android did some changes to cryptography in 9.0, I'm not sure if they are related or I've just missed a setting here: https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html

seperot commented 5 years ago

On further investigating it's the line in my code: .securityProvider(Security.getProvider("BC")) That is causing issues. I've removed the line for now and it's working again which is cool as a temporary fix.

patrickfav commented 5 years ago

Hi @seperot

This line

.securityProvider(Security.getProvider("BC"))

tells Armadillo to use the Bouncy Castle (BC) security provider. Since the early days bouncy castle seemed to be present during runtime in a random version, but Android does not guarantee any functionality of BC or which ciphers it supports. Therefore it was always a gamble using it as it could work on device A but break on device B. (This is the reason Spongy Castle was created, which is a repacking of BC with a different package name.)

The link you posted describes how Android will deprecate some functionality of the BC provider. Im not sure which of the functionality was deprecated. I however would recommend NOT using the BC provider. If you must, use a defined version of spongy castle if you have a specific need for it (see README Design Choices -> "Use of JCA as Provider for cryptographic primitives") as the behaviour of BC was never guaranteed (as stated before)

patrickfav commented 5 years ago

To just to be clear. By saying "I however would recommend NOT using the BC provider." I mean, not setting any security provider, but to use the Android provided one (which is uses Conscrypt since Android 7 AFAIK). The advantage is, that you profit from security fixes of the devices ROMs.

Setting the security provider is only recommended if you are exactly know what you are doing (which means you require specific implementations for any reason).

If you have any further question just put them here or create a new issue. I'll close this issue for now.