0

Anyone had success in using Jetpack Security for encryption with two separate master keys? The use case for this is having one set of data encrypted with a "regular" key and another with a key with additional biometric protection.

Tried the following with just two separate keys with the same spec just for testing:

class MainActivity : AppCompatActivity() {

    private val firstMasterKey by lazy {
        MasterKeys.getOrCreate(provideKeyGenParameters("aliasFirst"))
    }

    private val secondMasterKey by lazy {
        MasterKeys.getOrCreate(provideKeyGenParameters("aliasSecond"))
    }

    private val firstEncryptedFile by lazy {
        EncryptedFile.Builder(
            File(filesDir, "firstFile"),
            this,
            firstMasterKey,
            EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
        )
            .build()
    }

    private val secondEncryptedFile by lazy {
        EncryptedFile.Builder(
            File(filesDir, "secondFile"),
            this,
            secondMasterKey,
            EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
        )
            .build()
    }

    private fun provideKeyGenParameters(alias: String) =
        KeyGenParameterSpec.Builder(
            alias,
            KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
        )
            .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
            .setKeySize(256)
            .build()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        saveFiles()
    }

    private fun saveFiles() {
        firstEncryptedFile.openFileOutput().use {
            it.write(ByteArray(1) { Byte.MIN_VALUE })
        }

        // if I comment this save it works fine
        // as soon as I uncomment it the app crashes
        secondEncryptedFile.openFileOutput().use {
            it.write(ByteArray(1) { Byte.MIN_VALUE })
        }
    }
}

but got InvalidProtocolBufferException: Protocol message contained an invalid tag (zero) as soon as the other key was used. This happens on both stable version and and latest alpha03.

I posted a bug report to Google about that https://issuetracker.google.com/issues/192470296 but I have no hope since based on the other reported bugs they don't care at all. Anyways, if you encounter the issue please star it, maybe someone will notice.

marcinm
  • 281
  • 1
  • 2
  • 11
  • `MasterKeys` is deprecated, according to the JavaDocs and source code. Have you tried a non-deprecated alternative? – CommonsWare Jul 02 '21 at 11:03
  • The easiest way to solve your problem and use standard libraries is this way: 1) generate a random key (e.g. 32 bytes for AES-256), 2) encrypt your content with this key, 3) encrypt the random key with a user password/input (e.g. using PBKDF2 for key derivation, AES-GCM as encryption mode) and store the output with a tag "user input". 4) encrypt the random key secondly with some input coming from biometric stuff (e.g. AES GCM again) and store the output with a tag "biometric input". 5) clear the random key from memory. For decryption, run either the user-input or biometric input data. – Michael Fehr Jul 02 '21 at 11:43
  • @CommonsWare yes tried also the MasterKey Builder from the latest alpha - same results. – marcinm Jul 05 '21 at 06:33
  • @MichaelFehr thanks for your comment, will think about this once the Jetpack solution is definitely off the table (and it seems it will be so) – marcinm Jul 05 '21 at 06:33

0 Answers0