keyring-rs icon indicating copy to clipboard operation
keyring-rs copied to clipboard

android: support system keystore

Open phlip9 opened this issue 2 years ago • 21 comments

Overview

Currently keyring-rs supports iOS but not Android. If we can extend support to Android, then keyring-rs handles all major platforms, desktop and mobile, which would be pretty cool : )

Issues

Sadly Android doesn't appear to expose any access to the platform keystore via the ndk ffi bindings. Any solution would have to go through the Java interface. I'm not super familiar with how this works, but the approach taken in app_dirs2 would probably work: https://github.com/app-dirs-rs/app_dirs2/blob/main/src/imp/platform/android.rs.

Options

(1) Platform KeyStore/TEE/enclave

Safest, but annoying implementation.

After a cursory scan of the Android docs, it seems the main interface to the platform TEE is something called KeyStore. You can configure an instance that stores key material in the platform enclave. Secrets in the enclave are not exportable, so you need an extra layer of indirection to get a keyring entry in memory.

My guess is that they expect most users to use the EncryptedFile API, which stores a single "master key" in the platform KeyStore and then stores master-key-encrypted per-file (?) keys in the app's SharedPreferences. These sub-keys are then used to actually encrypt/decrypt a file on-disk.

The EncryptedFile API docs look like they have some sharp edges though:

Class used to create and read encrypted files. WARNING: The encrypted file should not be backed up with Auto Backup. When restoring the file it is likely the key used to encrypt it will no longer be present. You should exclude all EncryptedFiles from backup using backup rules. Be aware that if you are not explicitly calling setKeysetPrefName() there is also a silently-created default preferences file created at

   ApplicationProvider
        .getApplicationContext()
        .getFilesDir()
        .getParent() + "/shared_prefs/__androidx_security_crypto_encrypted_file_pref__"

This preferences file (or any others created with a custom specified location) also should be excluded from backups.

Challenges

(2) Just stick files in the application data directory

A simpler approach is to just dump keyring-rs entries into the application's data directory. I believe each application's data directory files are sandboxed and inaccessible to any other applications (unless the device is rooted of course).

The internal storage filesystem (where apps store their data) is also encrypted and only accessible after the user unlocks the device.

Challenges

This approach is definitely easier--we can probably reuse the approach in app_dirs2 verbatim.

phlip9 avatar May 22 '23 16:05 phlip9

One thing to note is that the keyutils backend might work on Android, since it's running a Linux kernel. But I'm not sure if the seccomp profiles apps are subject to would allow the syscalls.

https://android-developers.googleblog.com/2017/07/seccomp-filter-in-android-o.html

landhb avatar May 22 '23 22:05 landhb

~~Nevermind, looks like it's explicitly blocked on Android.~~

~~But then they also have this core utility. So I'm not sure. Probably worth a shot to see.~~

It might work since it seems the init process uses keyctl: https://github.com/aosp-mirror/platform_system_core/blob/1f7c08e2412c8316f4978259eaace0d3d778306a/init/init.cpp#L958. So depends if the seccomp profile is applied afterwards and is different for child processes, but that comment makes it seem like it's intended for child processes to have access to the session keyring. Since the File Based Encryption (FBE) keys, mentioned in part 2 above are stored there. https://github.com/aosp-mirror/platform_system_core/blob/1f7c08e2412c8316f4978259eaace0d3d778306a/init/fscrypt_init_extensions.cpp#L49

landhb avatar May 23 '23 14:05 landhb

I think I like the simplicity of just using the native app filesystem, which seems sufficiently protected in the same way that the typical gnome keyring is (by the user's login). But I don't really have time to work on this now, as it would require me to understand Android app development (which I've never tried). So if someone wants to take a shot at this, please do!

brotskydotcom avatar May 24 '23 19:05 brotskydotcom

Have any of you tried this crate https://github.com/dodorare/android-tools-rs , I think in combination with app_dirs2 and then rusqlite for persistent storage or binding SharedPrefrence java interface, can be a sufficient solution.

Zack-Xb avatar Jul 14 '23 10:07 Zack-Xb

https://github.com/dodorare/android-tools-rs/tree/main runs keytool from command line so this has to be changed.

Zack-Xb avatar Jul 14 '23 10:07 Zack-Xb

This can be done if we add a java module named keystore and it would have to be bridged manually in android studio as a new module, in rust we'd use jni to invoke the methods in java. Will be open sourcing this implementation in our app later this year, I'll make sure to find the time and create a branch here with a solution and docs.

Zack-Xb avatar Jan 21 '24 08:01 Zack-Xb

Hello, I'm wondering if there's any open source solution for using the Android keyring yet? I'm building an app which needs to store an encryption key in the system's native keyring, but it also needs to work on all of MacOS/Windows/Linux/iOS/Android.

Rigidity avatar Feb 25 '24 23:02 Rigidity

@Rigidity Here you go this is the library I have developed and been using. Be cautious re using this in production cause have not tested this and its security implications rigorously enough. You can then use jni bindings from your rust project to call the functions in Java, hit me up if you need any help and if you see anything that can be improved of which there is a lot feel free to contribute.

https://github.com/AvailX/keystore_module

Zack-Xb avatar Mar 23 '24 13:03 Zack-Xb

@Rigidity have any idea if this library support biometrics for iOS ?

Zack-Xb avatar Mar 23 '24 13:03 Zack-Xb

@Zack-Xb Are you asking whether the keychain rust crate supports biometrics for iOS? If so, the answer is yes - it uses the iOS native keychain and so supports biometrics.

clickonetwo avatar Mar 24 '24 05:03 clickonetwo