- Android Keystore: что это, для чего нужен, как создать ключ
- Кратко о Keystore
- Как пользоваться KeyStore
- Принципы создания сертификата
- Принципы создания ключа
- Android Keystore System
- In this document
- Blog articles
- Unifying Key Store Access in ICS
- Security Features
- Extraction Prevention
- Key Use Authorizations
- Choosing Between a Keychain or the Android Keystore Provider
- Using Android Keystore Provider
- Generating a New Private Key
- Generating a New Secret Key
- Working with Keystore Entries
- Listing Entries
- Signing and Verifying Data
- Requiring User Authentication For Key Use
- Finding your Keystore’s Signature
- For Debug / Non-Custom Signed Builds
- For Release / Custom Signed Builds
- How to use the Android Keystore to store passwords and other sensitive information
- Preparation
- Securing Secret Key In Android Using Keystore
- ENCRYPTING DATA
- DECRYPTING DATA
- In HomeScreen.java
- CONCLUSION:
Android Keystore: что это, для чего нужен, как создать ключ
Конфиденциальность в приложении – пункт №1, которому разработчик должен уделить особое внимание. Самый распространенный способ защиты информации – шифрование данных. К нему относятся криптографические символы, симметрия и асимметрия шифра, сертификаты. Keystore – основной ресурс, где можно создать ключ безопасности. Об этом и поговорим ниже.
Кратко о Keystore
Keystore – это хранилище секретной информации, которое применяется Java-прогами с целью зашифровать данные, аутентифицировать и установить HTTPS соединение. Например, для аутентификации пользователя и сервера, между которыми установлен SSL, требуется ключ приватности и сертификат.
Для односторонней аутентификации кейстор применяется только на серверной части. При двусторонней происходит сертификатный обмен (т.е. у обоих сторон есть ключ приватности). Иными словами, кейстор необходим для того, чтобы быстро идентифицировать обладателя ключа.
Java «распознает» такие способы хранения данных в кейстор:
- Jks. Это тип хранения по умолчанию, применяется чаще всего;
- Jceks. Альтернатива предыдущему типу, на основе которой внедряется усложненное шифрование данных (на базе Triple DES). Если изначально применялся jks, хранилище можно обновить на jceks с помощью кейтула;
- Pkcs12. Это тип хранения, используемый при необходимости транспортировки закрытых ключей.
Записи в кейсторе именуются уникальными подписями. В стандартной версии Keystore ключи защищены паролем. Более того, целое хранилище можно защищать паролем. Доверенные сертификаты для ПО Android распределяются в директории Jre-Lib-Security-Cacerts (запароленные под «changeit»).
Как пользоваться KeyStore
Данные в хранилище делятся на 2 группы: ключевые записи (private и public) и доверенные сертификаты. Ключевые записи используются для криптографического шифрования, содержат идентифицированную информацию о клиенте. Доверенные сертификаты не используются тогда, когда требуется key закрытого типа.
Для отделения ключевых записей от сертификатов используются разные хранилища: для персональных ключей и доверенных (включая СЦА). Таким образом, обеспечивается повышенная защита данных.
Принципы создания сертификата
Используйте команду «-genkey» и укажите период действия сертификата («-validity»). Далее создается пара RSA-ключей, действие которых будет длиться 12 месяцев с момента реализации. Закрытые ключи защищаются в хранилище паролем, а открытые «конвертируются» в самодподписывающийся» сертификат.
Если вы не обнаружили искомый ключ в хранилище, его можно создать с помощью кейтула. При использовании данного инструмента система запросит ввести пароль от хранилища и закрытого ключа. Формат создаваемого сертификата – Х.509. Параметры указывайте в виде командной опции. Задавайте информацию о компании, способе размещения в хранилище, сроке действия сертификата.
Принципы создания ключа
Чтобы создать ключ, используйте команду «-genkeypair». Она автоматически клонирует ключ под названием «keypair» и перемещает элементы в хранилище. Открытые ключи «охватываются» форматом Х.509 – т.е. самоподписным сертификатом. Чтобы увидеть список ключей и сертификатов, хранимых в кейсторе, введите команду «-list», после чего укажите путь к информации.
Источник
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.
Источник
Finding your Keystore’s Signature
The MD5 or SHA1 signature of a Xamarin.Android app depends on the .keystore file that was used to sign the APK. Typically, a debug build will use a different .keystore file than a release build.
For Debug / Non-Custom Signed Builds
Xamarin.Android signs all debug builds with the same debug.keystore file. This file is generated when Xamarin.Android is first installed.The steps below detail the process for finding the MD5 or SHA1 signature of the default Xamarin.Android debug.keystore file.
Locate the Xamarin debug.keystore file that is used to sign the app. By default, the keystore that is used to sign debug versions of a Xamarin.Android application can be found at the following location:
C:\Users\USERNAME\AppData\Local\Xamarin\Mono for Android\debug.keystore
Information about a keystore is obtained by running the keytool.exe command from the JDK. This tool is typically found in the following location:
C:\Program Files (x86)\Java\jdkVERSION\bin\keytool.exe
Add the directory containing keytool.exe to the PATH environment variable. Open a Command Prompt and run keytool.exe using the following command:
When run, keytool.exe should output the following text. The MD5: and SHA1: labels identify the respective signatures:
Locate the Xamarin debug.keystore file that is used to sign the app. By default, the keystore that is used to sign debug versions of a Xamarin.Android application can be found at the following location:
/.local/share/Xamarin/Mono for Android/debug.keystore
Information about a keystore is obtained by running the keytool command from the JDK. This tool is typically found in the following location:
/System/Library/Java/JavaVirtualMachines/VERSION.jdk/Contents/Home/bin/keytool
Add the directory containing keytool to the PATH environment variable. Open a Terminal and run keytool by using the following command:
When run, keytool should output the following text. The MD5: and SHA1: labels identify the respective signatures:
For Release / Custom Signed Builds
The process for release builds that are signed with a custom .keystore file are the same as above, with the release .keystore file replacing the debug.keystore file that is used by Xamarin.Android. Replace your own values for the keystore password, and alias name from when the release keystore file was created.
When the Visual Studio Distribute wizard is used to sign a Xamarin.Android app, the resulting keystore resides in the following location:
C:\Users\USERNAME\AppData\Local\Xamarin\Mono for Android\Keystore\alias\alias.keystore
For example, if you followed the steps in Create a New Certificate to create a new signing key, the resulting example keystore resides in the following location:
C:\Users\USERNAME\AppData\Local\Xamarin\Mono for Android\Keystore\chimp\chimp.keystore
For more information about signing a Xamarin.Android app, see Signing the Android Application Package.
When the Visual Studio for Mac Sign and Distribute. wizard to sign your app, the resulting keystore resides in the following location:
For example, if you followed the steps in Create a New Certificate to create a new signing key, the resulting example keystore resides in the following location:
Источник
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.
Источник
Securing Secret Key In Android Using Keystore
At some point in time, we all wanted to keep our data secure from being hacked/reverse engineered. The basic security mechanisms like,
a. ProGuard, ShrinkResources & minifyEnabled
b. Hiding in Manifest
c. Hiding in Build.Gradle
d. Storing in MySQL DB/Room DB/SharedPreference
e. Hiding in Strings.xml.
All these methods fail to provide maximum security. The most common and known logic of securing the key can be bypassed either by reversing and taking it from dex->jar file or by rooting the device and accessing the device storage.
But, there is one more method that beats them all. The mechanism which is generally used by applications for storing very sensitive data like Credit Card details, Bank Account and such.
Keystore is bound to hardware security which is generally used to store cryptographic keys. It becomes incredibly difficult for hackers to get access to it since a Keystore is very specific to every application. More of introduction done let us jump to the code now —
Declare few variables in Cryptor.java
private static final String TRANSFORMATION = “AES/GCM/NoPadding”;
private static final String ANDROID_KEY_STORE = “AndroidKeyStore”;
private byte[] iv;
private KeyStore keyStore;
private static final String SAMPLE_ALIAS = “MYALIAS”;
a. TRANSFORMATION is used for setting the algorithm which will be used for encoding.
b. iv is known as Initialization Vector which is an arbitrary number used along with a secret key for encryption. (It can be stored in public storage like SharedPreference, Room DB or MySQL DB).
c. SAMPLE_ALIAS is used to access the entity stored inside the Keystore.
ENCRYPTING DATA
For encrypting a value with the Keystore, we can do it by,
a. Create an object of the Cryptor class.
b. Use a setIv method to init the cipher using a secret key in Cryptor class.
c. Encrypt the text using an encryption function defined in Cryptor class.
d. Store the Iv and encrypted text (The Iv can be made public and it does not cause any issue) in SharedPreference or Room Database.
In Cryptor.java, we define the following functions
2. getSecretKey_en() method :
3. encryptText(String string_to_encrypt) :
4. encryptData(String text_to_encrypt) :
Explanation: We generate a secret key using the keyStore with specific algorithms and the ALIAS. the secret key which is generated is used to init the cipher and get the IV. The encrypt text function uses the text and the iv to encrypt the text in the Keystore and gives the encrypted text which can be stored in any general storage medium.
DECRYPTING DATA
For decrypting a value with the Keystore, we can do it by,
a. Create an object of the Cryptor class.
b. Initialize the KeyStore instance.
c. Use the decrypt function by passing the encrypted text and the iv (stored in SharedPreference or Room Database).
In HomeScreen.java
In Cryptor.java, add the following functions
2. decryptText(String encrypted_string, String iv) :
3. decryptData(String encrypted_string, byte[] Iv) :
Explanation: While decrypting, we get the stored Iv and encrypted text stored in our one of the storage medium. We initialize the Keystore using the ANDROID_KEY_STORE and decrypt the text using the Iv and by the init and doFinal method of the Cipher.
CONCLUSION:
So, with the above implementation, secrets are now safe in the KeyStore. Why it is probably the best method is because KeyStore is very specific to the application. It cannot be retrieved and hence the text cannot be decrypted without it. Many applications which stores the Credit Card and other sensitive data of the users use this encryption method to keep it safe.
For the entire code, you can look into my GitHub repository.
Источник