How to overwrite EncryptedFile on Android?
Asked Answered
S

1

10

Using Android's EncryptedFile (androidx.security:security-crypto:1.1.0-alpha01), I can successfully write a file using the following code

File file = new File(context.getFilesDir() + File.separator + filename);
KeyGenParameterSpec keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC;
EncryptedFile encryptedFile = null;
try {
    String masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec);
    encryptedFile = new EncryptedFile.Builder(
            file,
            context,
            masterKeyAlias,
            EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
    ).build();
} catch (Exception exception) {
    // log error
}

// write file
try {
    BufferedWriter bufferedWriter = new BufferedWriter(
            new OutputStreamWriter(encryptedFile.openFileOutput()));
    bufferedWriter.write(string);
    bufferedWriter.close();
} catch (Exception exception) {
    // log error
}

However, when attempting to overwrite the same file, the write operation fails and the following is thrown

java.io.IOException: output file already exists, please use a new file

I found this to be an explicit check in EncryptedFile's openFileOutput()

if (mFile.exists()) {
    throw new IOException("output file already exists, please use a new file: "
            + mFile.getName());
}

To fix this, I was able to successfully overwrite by deleting the file if it existed before using it to build the EncryptedFile

File file = new File(context.getFilesDir() + File.separator + filename);
if (file.exists()) { file.delete(); }

... remaining code from top snippet above

This seems like a hack, but I also don't understand the choice to throw an exception for mFile.exists() in openFileOutput(). Is there a correct/better way to overwrite an EncryptedFile?

Stall answered 28/7, 2020 at 5:10 Comment(2)
Deleting the file first seems fine to me.Keifer
I've had some cases where the if (file.exists()) { file.delete(); } does not work, and this exception: throw new IOException("output file already exists, please use a new file: " + mFile.getName()); is still thrown. Any ideas?Avesta
B
0

For anyone struggling to write to a file more then once and reaching this error. Note that it is possible to write to an encrypted file for only once. To make it work remove the old file as follow:

File file = new File(getApplicationContext().getFilesDir(),"secret_data.bin");
if(file.exists()){
  file.delete();
}
this.encryptedFile = new EncryptedFile.Builder(
    getApplicationContext(),
    file,
    key,
    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB).build();
Bottali answered 27/4, 2024 at 11:32 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.