Store key in android keystore

Android Keystore System

In this document

Blog articles

Unifying Key Store Access in ICS

The Android Keystore system lets you store cryptographic keys in a container to make it more difficult to extract from the device. Once keys are in the keystore, they can be used for cryptographic operations with the key material remaining non-exportable. Moreover, it offers facilities to restrict when and how keys can be used, such as requiring user authentication for key use or restricting keys to be used only in certain cryptographic modes. See Security Features section for more information.

The Keystore system is used by the KeyChain API as well as the Android Keystore provider feature that was introduced in Android 4.3 (API level 18). This document goes over when and how to use the Android Keystore provider.

Security Features

Extraction Prevention

Key Use Authorizations

Supported key use authorizations fall into the following categories:

  • cryptography: authorized key algorithm, operations or purposes (encrypt, decrypt, sign, verify), padding schemes, block modes, digests with which the key can be used;
  • temporal validity interval: interval of time during which the key is authorized for use;
  • user authentication: the key can only be used if the user has been authenticated recently enough. See Requiring User Authentication For Key Use.

As an additional security measure, for keys whose key material is inside secure hardware (see KeyInfo.isInsideSecurityHardware() ) some key use authorizations may be enforced by secure hardware, depending on the Android device. Cryptographic and user authentication authorizations are likely to be enforced by secure hardware. Temporal validity interval authorizations are unlikely to be enforced by the secure hardware because it normally does not have an independent secure real-time clock.

Whether a key’s user authentication authorization is enforced by the secure hardware can be queried using KeyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware() .

Choosing Between a Keychain or the Android Keystore Provider

Use the KeyChain API when you want system-wide credentials. When an app requests the use of any credential through the KeyChain API, users get to choose, through a system-provided UI, which of the installed credentials an app can access. This allows several apps to use the same set of credentials with user consent.

Use the Android Keystore provider to let an individual app store its own credentials that only the app itself can access. This provides a way for apps to manage credentials that are usable only by itself while providing the same security benefits that the KeyChain API provides for system-wide credentials. This method requires no user interaction to select the credentials.

Using Android Keystore Provider

To use this feature, you use the standard KeyStore and KeyPairGenerator or KeyGenerator classes along with the AndroidKeyStore provider introduced in Android 4.3 (API level 18).

AndroidKeyStore is registered as a KeyStore type for use with the KeyStore.getInstance(type) method and as a provider for use with the KeyPairGenerator.getInstance(algorithm, provider) and KeyGenerator.getInstance(algorithm, provider) methods.

Generating a New Private Key

Generating a new PrivateKey requires that you also specify the initial X.509 attributes that the self-signed certificate will have. You can replace the certificate at a later time with a certificate signed by a Certificate Authority.

Generating a New Secret Key

Working with Keystore Entries

Using the AndroidKeyStore provider takes place through all the standard KeyStore APIs.

Listing Entries

List entries in the keystore by calling the aliases() method:

Signing and Verifying Data

Sign data by fetching the KeyStore.Entry from the keystore and using the Signature APIs, such as sign() :

Читайте также:  Андроид почему не синхронизируются все контакты

Similarly, verify data with the verify(byte[]) method:

Requiring User Authentication For Key Use

When generating or importing a key into the AndroidKeyStore you can specify that the key is only authorized to be used if the user has been authenticated. The user is authenticated using a subset of their secure lock screen credentials (pattern/PIN/password, fingerprint).

This is an advanced security feature which is generally useful only if your requirements are that a compromise of your application process after key generation/import (but not before or during) cannot bypass the requirement for the user to be authenticated to use the key.

Источник

How to use the Android Keystore to store passwords and other sensitive information

Preparation

Before we begin coding, it is helpful to understand a bit about the Android Keystore, and it’s capabilities. The Keystore is not used directly for storing application secrets such as password, however, it provides a secure container, which can be used by apps to store their private keys, in a way that’s pretty difficult for malicious (unauthorised) users and apps to retrieve.

As its name suggests, an app can store multiple keys in the Keystore, but an app can only view, and query, its own keys. Ideally, with the keystore, an app would generate/or receive a private/public key pair, which would be stored in the keystore. The public key can then be used to encrypt application secrets, before being stored in the app specific folders, with the private key used to decrypt the same information when needed.

Although the Android Keystore provider was introduced in API level 18 (Android 4.3), the Keystore itself has been available since API 1, restricted to use by VPN and WiFi systems.

The Keystore itself is encrypted using the user’s own lockscreen pin/password, hence, when the device screen is locked the Keystore is unavailable. Keep this in mind if you have a background service that could need to access your application secrets.

Источник

Storing Secret Keys in Android

Often your app will have secret credentials or API keys that you need to have in your app to function but you’d rather not have easily extracted from your app.

If you are using dynamically generated secrets, the most effective way to store this information is to use the Android Keystore API. You should not store them in shared preferences without encrypting this data first because they can be extracted when performing a backup of your data.

The alternative is to disable backups by setting android:allowBackup in your AndroidManifest.xml file:

You can also specify which files to avoid backups too by reviewing this doc.

For storing fixed API keys, the following common strategies exist for storing secrets in your source code:

The simplest approach for storing secrets in to keep them as resource files that are simply not checked into source control. The approaches below two ways of accomplishing the same goal.

First, create a file apikey.properties in your root directory with the values for different secret keys:

Double quotes are required.

To avoid these keys showing up in your repository, make sure to exclude the file from being checked in by adding to your .gitignore file:

Next, add this section to read from this file in your app/build.gradle file. You’ll also create compile-time options that will be generated from this file by using the buildConfigField definition:

You can now access these two fields anywhere within your source code with the BuildConfig object provided by Gradle:

Now you have access to as many secret values as you need within your app, but will avoid checking in the actual values into your git repository. To read more about this approach, check out this article or this other article.

Start by creating a resource file for your secrets called res/values/secrets.xml with a string pair per secret value:

Once these keys are in the file, Android will automatically merge it into your resources, where you can access them exactly as you would your normal strings. You can access the secret values in your Java code with:

Читайте также:  Шарики зума для андроид

If you need your keys in another XML file such as in AndroidManifest.xml , you can just use the XML notation for accessing string resources:

Since your secrets are now in an individual file, they’re simple to ignore in your source control system (for example, in Git, you would add this to the ‘.gitignore’ file in your repository) by entering this on the command line within your project git repository:

Verification: To make sure this worked, check the .gitignore file within your git repository, and make sure that this line referencing secrets.xml exists. Now, go to commit files to Git and make sure that you do not see the secrets.xml file in the staging area. You do not want to commit this file to Git.

This process is not bulletproof. As resources, they are somewhat more vulnerable to decompilation of your application package, and so they are discoverable if somebody really wants to know them. This solution does, however, prevent your secrets just sitting in plaintext in source control waiting for someone to use, and also has the advantage of being simple to use, leveraging Android’s resource management system, and requiring no extra libraries.

However, none of these strategies will ensure the protection of your keys and your secrets aren’t safe. The best way to protect secrets is to never reveal them in the code in the first place. Compartmentalizing sensitive information and operations on your own backend server/service should always be your first choice.

If you do have to consider a hiding scheme, you should do so with the realization that you can only make the reverse engineering process harder and may add significant complication to the development, testing, and maintenance of your app in doing so. Check out this excellent StackOverflow post for a detailed breakdown of the obfuscation options available.

The simplest and most straightforward approach is outlined below which is to store your secrets within a resource file. Keep in mind that most of the other more complex approaches above are at best only marginally more secure.

Another way to make your keys hard to reverse engineer is to save them in the NDK. A recommanded implementation as done in hidden-secrets-gradle-plugin :

  • secret is obfuscated using the reversible XOR operator so it never appears in plain sight,
  • obfuscated secret is stored in a NDK binary as an hexadecimal array, so it is really hard to spot / put together from a disassembly,
  • the obfuscating string is not persisted in the binary to force runtime evaluation (ie : prevent the compiler from disclosing the secret by optimizing the de-obfuscation logic),
  • optionnaly, anyone can provide it’s own encoding / decoding algorithm when using the plugin to add an additional security layer.

To understand the Android Keystore API, you must first understand that encrypting secrets requires both public key and symmetric cryptography. In public key cryptography, data can be encrypted with one key and decrypted with the other key. In symmetric cryptography, the same key is used to encrypt and decrypt the data. The Keystore API uses both types of cryptography in order to safeguard secrets.

A public/private key RSA pair is generated, which is stored in the Android device’s keystore and protected usually by the device PIN. An AES-based symmetric key is also generated, which is used to encrypt and decrypt the secrets. The app needs to store this AES symmetric key to later decode, so it is encrypted by the RSA public key first before persisted. When the app runs, it gives this encrypted AES key to the Keystore API, which will decode the data using its private RSA key. In this way, data cannot be decoded without the use of the device keystore.

Read this Medium blog for more information about how to use the Keystore API. Do not use the Qlassified Android library because it introduces an additional 20K methods to your Android program. You can use the Android Vault library, which will also help facilitate the rotation of RSA keys, which usually have an expiration date of 1-5 years.

Читайте также:  Fut 22 draft android

See also the official Google sample for using the Android Keystore.

Источник

Android Security, Keystore and Fingerprint API. Creating Lock Screen for your app.

How to protect sensitive data in your Android application. In this article, I’ll tell about AndroidKeystore, Fingerprints and how to use it to protects some of your data such as passwords, tokens, etc.

This article is based on PFLockScreen library I created. You can use it in your application. If you have some issues or ideas fill free to create an issue on GitHub or write me a message.

About Android Keystore.

The Android Keystore system lets you store cryptographic keys in a container to make it more difficult to extract from the device. Once keys are in the keystore, they can be used for cryptographic operations with the key material remaining non-exportable.

You can use Android Keystore to encrypt some sensitive data like passwords. For example, your application required a password to make a purchase and you want the application to remember user’s password for some short amount of time (15 min — 30 min) so a user doesn’t need to input it again. The similar logic you can find, for instance, in Apple AppStore. Within this time input password again is not required. For this situation, you can use keystore to encrypt and save the password.

First, you need to load a keystore.

Next step is to generate an encryption key.

What is going on here? You initialize KeyGenerator, with your alias name and purposes (Encryption and Decryption).

Set encryption algorithm and parameters. You can use different algorithms to create a symmetric or asymmetric key, etc (Use KeyPairGenerator or KeyGenerator).

If you want you can protect this key with device pin code (The one you use to lock your device) or fingerprint with the setUserAuthenticationRequired method.

It’s mean that to get access to the encryption keys from keystore and decrypt your data you will need to use a device authorization.

But don’t worry. Only your application can get its keystore data. But in this case, there is additional security level required user participation.

After you load keystore and generate key next set is creating a Cipher object.

This class provides the functionality of a cryptographic cipher for encryption and decryption.

“RSA/ECB/OAEPWithSHA-256AndMGF1Padding” — “algorithm/mode/padding” or can be just “algorithm” depends on your key generator parameters.

Encrypt

To encrypt out data we need to initialize cipher object.

A known bug in Android 6.0 (API Level 23) causes user authentication-related authorizations to be enforced even for public keys. To work around this issue extract the public key material to use outside of Android Keystore.

After we did all the steps we finally do encoding. byte[] bytes = cipher.doFinal(input.getBytes()); String encoded = Base64.encodeToString(bytes, Base64.NO_WRAP);

This encoded string we got in result we can save somewhere in SharedPreferences or using Accounts API.

Decrypt

To decode string we got before, first, we need to preparing Cipher to decode.

If before we set the “user authentication required” parameter to false before, we can just decode.

Using fingerprint API to confirm user and decryption.

Google added Fingerprint API only in Android 6.0 and even new devices not always have a fingerprint scanner. So you have to check you if a device has fingerprint hardware.

To check if a device has a scanner: FingerprintManagerCompat.from(context).isHardwareDetected();

To check if a user added his fingerprint to the device: FingerprintManagerCompat.from(context).hasEnrolledFingerprints();

If we going to use Fingerprint API for decoding (KeyGenerator’s userAuthenticationRequired is true), then we need to check also if your screen is locked with pin or pattern.

If we are using Fingerprint for decryption we need to pass CryptoObject. Otherwise, CryptoObject can be null.

Next step is letting the system know that we are ready to try to authenticate with fingerprint:

If we want a system to stop listening for fingerprint we can cancel.

To get an event about successful or unsuccessful attempts use

You can find code example in my PFLockScreen library.

If you like the article please press 👏 button.

Источник

Оцените статью