Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AndroidX Security EncryptedSharedPreferences v1.1.0 /w API 21 issue

I decided to use new EncryptedSharedPreferences from AndroidX Security library. Since the app is supporting API 21 and higher, I decided to try out this new v1.1.0-alpha02 version, since it supports API 21+

So, I succeded to make the implementation for API 23+, but for older versions where Android KeyStore is not supported, I couldn't make it right, and there are no exact instructions how the master key should be created to make it work somehow.

The code for initializing SharedPrefs:

EncryptedSharedPreferences.create(         "prefs_name",         createMasterKey(),         App.appContext,         EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,         EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM     ) 

with this function for creating master key

   private fun createMasterKey(): String {         return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {             MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)         } else {             val alias = "my_alias"             val start: Calendar = GregorianCalendar()             val end: Calendar = GregorianCalendar()             end.add(Calendar.YEAR, 30)              val spec = KeyPairGeneratorSpec.Builder(App.appContext)                 .setAlias(alias)                 .setSubject(X500Principal("CN=$alias"))                 .setSerialNumber(BigInteger.valueOf(abs(alias.hashCode()).toLong()))                 .setStartDate(start.time).setEndDate(end.time)                 .build()              val kpGenerator: KeyPairGenerator = KeyPairGenerator.getInstance(                 "RSA",                 "AndroidKeyStore"             )             kpGenerator.initialize(spec)             val kp: KeyPair = kpGenerator.generateKeyPair()                          kp.public.toString()         }     } 

I found this solution somewhere out there, but it's not verified (no confirmation that it actually works), but it seems it should work.

When using this code block for API 21 and 22, the error appears on creating EncryptedSharedPreferences, and it says: Method threw 'com.google.crypto.tink.shaded.protobuf.InvalidProtocolBufferException' exception. Protocol message contained an invalid tag (zero).

Did someone find the solution for this implementation, or do you know why is this happening? I think this would help a lot of people, since there is no exact explanation what should this master key contain.

Thanks in advance!

like image 482
aherman Avatar asked Aug 26 '20 12:08

aherman


People also ask

What is EncryptedSharedPreferences?

EncryptedSharedPreferences. Wraps the SharedPreferences class and automatically encrypts keys and values using a two-scheme method: Keys are encrypted using a deterministic encryption algorithm such that the key can be encrypted and properly looked up. Values are encrypted using AES-256 GCM and are non-deterministic.

What does EncryptedSharedPreferences encrypt when saving key value pairs?

Using EncryptedSharedPreferences The data stores in the form of key-value pairs. JetSec provides an encrypted version of SharedPreferences , named EncryptedSharedPreferences , that provides strong security while maintaining performance for reading the key-value data. Keys and values can both be encrypted.


1 Answers

Add to manifest android:allowBackup="false" android:fullBackupContent="false"

Because after uninstalling the application you still have backed up your crypto file which you definitely can't decrypt after installing a new version.

like image 150
Timur Munatayev Avatar answered Sep 27 '22 18:09

Timur Munatayev