Sistem Android Keystore

Sistem Android Keystore memungkinkan Anda menyimpan kunci kriptografik dalam kontainer agar lebih sulit untuk diekstrak dari perangkat. Setelah kunci berada pada keystore, mereka bisa digunakan untuk operasi kriptografik dengan material utama yang tersisa tidak dapat diekspor. Selain itu, keystore menawarkan fasilitas untuk membatasi kapan dan bagaimana kunci bisa digunakan, seperti mengharuskan autentikasi pengguna untuk penggunaan kunci atau membatasi kunci agar hanya digunakan dalam mode kriptografik tertentu. Lihat bagian Fitur Keamanan untuk informasi selengkapnya.

Sistem Keystore digunakan oleh KeyChain API serta fitur penyedia Android Keystore yang diperkenalkan di Android 4.3 (API level 18). Dokumen ini menjelaskan tentang kapan dan cara penggunaan penyedia Android Keystore.

Fitur Keamanan

Sistem Android Keystore melindungi material utama dari penggunaan yang tidak sah. Pertama, Android Keystore mengurangi penggunaan yang tidak sah dari material utama di luar perangkat Android dengan mencegah ekstraksi material utama dari proses aplikasi dan dari perangkat Android secara keseluruhan. Kedua, Android KeyStore mengurangi penggunaan material utama yang tidak sah pada perangkat Android dengan membuat aplikasi yang menentukan penggunaan berizin dari kunci dan kemudian menerapkan pembatasan ini luar pemrosesan aplikasi.

Pencegahan Ekstraksi

Material utama dari kunci Keystore Android dilindungi dari ekstraksi dengan menggunakan dua langkah keamanan:
  • Material utama tidak masuk ke dalam proses aplikasi. Bila sebuah aplikasi melakukan operasi kriptografik menggunakan kunci Android Keystore, plaintext di belakang layar, ciphertext, dan pesan yang didaftar atau diverifikasi diberikan ke proses sistem yang melakukan operasi kriptografi. Jika proses aplikasi tidak aman, penyerang mungkin bisa menggunakan kunci aplikasi, namun tidak akan dapat mengekstrak material utama (misalnya, untuk digunakan di luar perangkat Android).
  • Material utama dapat terikat pada perangkat keras yang aman (misalnya, Trusted Execution Environment (TEE), Secure Element (SE)) dari perangkat Android. Bila fitur ini diaktifkan untuk sebuah kunci, material utamanya tidak akan terekspos di luar perangkat keras aman. Jika Android OS disusupi atau penyerang bisa membaca storage internal perangkat, penyerang mungkin dapat menggunakan setiap kunci Android Keystore aplikasi pada perangkat Android, namun tidak akan bisa mengambilnya dari perangkat. Fitur ini diaktifkan hanya jika perangkat keras aman dari perangkat mendukung kombinasi tertentu algoritme kunci, mode blok, skema padding, dan inti sari dengan kunci yang diotorisasi untuk digunakan. Untuk memeriksa apakah fitur ini diaktifkan untuk suatu kunci, berlakukan KeyInfo untuk kunci tersebut dan periksa nilai yang kembali dari KeyInfo.isInsideSecurityHardware().

Otorisasi Penggunaan Kunci

Untuk meminimalkan penggunaan kunci yang tidak sah pada perangkat Android, Android Keystore membolehkan aplikasi untuk menentukan penggunaan kunci yang diizinkan saat membuat atau mengimpor kunci. Setelah kunci dibuat atau diimpor, otorisasinya tidak dapat diubah. Otorisasi kemudian diberlakukan oleh Android Keystore setiap kali kunci digunakan. Ini adalah fitur keamanan canggih yang biasanya berguna hanya jika persyaratan Anda adalah kondisi bahaya dari proses aplikasi setelah kunci dibuat/diimpor (namun tidak sebelum atau selama) tidak bisa menyebabkan penggunaan yang tidak diizinkan dari kunci tersebut.

Otorisasi penggunaan kunci yang didukung termasuk ke dalam kategori berikut:

  • kriptografi: algoritme kunci yang diotorisasi, operasi atau fungsi (encrypt, decrypt, sign, verify), skema padding, mode blok, inti sari dengan kunci yang dapat digunakan;
  • interval validitas temporer: interval waktu saat kunci yang diotorisasi bisa digunakan;
  • autentikasi pengguna: kunci hanya bisa digunakan jika telah diautentikasi pengguna baru-baru ini. Lihat Mengharuskan Autentikasi Pengguna Untuk Penggunaan Kunci.

Sebagai langkah keamanan tambahan, untuk kunci yang material utamanya berada dalam perangkat keras aman (lihat KeyInfo.isInsideSecurityHardware()) beberapa otorisasi penggunaan kunci dapat diberlakukan oleh perangkat keras aman, bergantung pada perangkat Android. Otorisasi kriptografik dan otorisasi autentikasi pengguna kemungkinan besar akan diberlakukan oleh perangkat keras aman. Otorisasi interval validitas temporer tampaknya tidak akan diberlakukan oleh perangkat keras aman karena biasanya tidak memiliki jam real-time yang aman serta independen.

Otorisasi autentikasi kunci pengguna yang diterapkan oleh perangkat keras aman bisa dikueri menggunakan KeyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware().

Memilih Antara Keychain atau Penyedia Android Keystore

Gunakan KeyChain API jika Anda menginginkan kredensial seluruh-sistem. Bila sebuah aplikasi meminta penggunaan kredensial apa pun melalui KeyChain API, pengguna bisa memilih, melalui sistem yang disediakan UI, apa kredensial terpasang yang dapat diakses aplikasi. Hal ini memungkinkan sejumlah aplikasi menggunakan kumpulan kredensial yang sama dengan izin pengguna.

Gunakan penyedia Android Keystore untuk mengizinkan setiap aplikasi menyimpan kredensial-nya sendiri yang hanya bisa diakses oleh aplikasi tersebut. Ini menyediakan cara bagi aplikasi untuk mengelola sendiri kredensial yang dapat digunakan sembari memberikan manfaat keamanan yang sama seperti yang diberikan KeyChain API untuk kredensial seluruh sistem. Metode ini tidak memerlukan interaksi pengguna untuk memilih kredensial.

Menggunakan Penyedia Android Keystore

Untuk menggunakan fitur ini, Anda menggunakan KeyStore standar dan KeyPairGenerator atau kelas KeyGenerator bersama dengan penyedia AndroidKeyStore yang diperkenalkan pada Android 4.3 (API level 18).

AndroidKeyStore terdaftar sebagai tipe KeyStore untuk digunakan bersama metode KeyStore.getInstance(type) dan sebagai penyedia untuk digunakan bersama metode KeyPairGenerator.getInstance(algorithm, provider) dan KeyGenerator.getInstance(algorithm, provider).

Membuat Kunci Privat Baru

Membuat sebuah PrivateKey baru mengharuskan Anda juga menentukan atribut X.509 awal yang akan memiliki sertifikat terdaftar-mandiri. Anda bisa menggunakan KeyStore.setKeyEntry untuk menggantikan sertifikat di kemudian hari dengan sertifikat yang didaftar oleh Otoritas Sertifikat (CA).

Untuk membuat kunci, gunakan KeyPairGenerator dengan KeyPairGeneratorSpec:

/*
 * Generate a new EC key pair entry in the Android Keystore by
 * using the KeyPairGenerator API. The private key can only be
 * used for signing or verification and only with SHA-256 or
 * SHA-512 as the message digest.
 */
KeyPairGenerator kpg = KeyPairGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
kpg.initialize(new KeyGenParameterSpec.Builder(
        alias,
        KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
        .setDigests(KeyProperties.DIGEST_SHA256,
            KeyProperties.DIGEST_SHA512)
        .build());

KeyPair kp = kpg.generateKeyPair();

Membuat Kunci Rahasia Baru

Untuk membuat kunci, gunakan KeyGenerator dengan KeyGenParameterSpec.

Bekerja dengan Entri Keystore

Penggunaan penyedia AndroidKeyStore berlangsung di seluruh KeyStore API standar.

Mencantumkan Entri

Cantumkan entri di keystore dengan memanggil metode aliases():

/*
 * Load the Android KeyStore instance using the the
 * "AndroidKeyStore" provider to list out what entries are
 * currently stored.
 */
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
Enumeration<String> aliases = ks.aliases();

Menandatangani dan Memverifikasi Data

Tanda tangani data dengan mengambil KeyStore.Entry dari keystore dan menggunakan Signature API, seperti sign():

/*
 * Use a PrivateKey in the KeyStore to create a signature over
 * some data.
 */
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);
if (!(entry instanceof PrivateKeyEntry)) {
    Log.w(TAG, "Not an instance of a PrivateKeyEntry");
    return null;
}
Signature s = Signature.getInstance("SHA256withECDSA");
s.initSign(((PrivateKeyEntry) entry).getPrivateKey());
s.update(data);
byte[] signature = s.sign();

Demikian pula, verifikasi data dengan metode verify(byte[]):

/*
 * Verify a signature previously made by a PrivateKey in our
 * KeyStore. This uses the X.509 certificate attached to our
 * private key in the KeyStore to validate a previously
 * generated signature.
 */
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);
if (!(entry instanceof PrivateKeyEntry)) {
    Log.w(TAG, "Not an instance of a PrivateKeyEntry");
    return false;
}
Signature s = Signature.getInstance("SHA256withECDSA");
s.initVerify(((PrivateKeyEntry) entry).getCertificate());
s.update(data);
boolean valid = s.verify(signature);

Mengharuskan Autentikasi Pengguna Untuk Penggunaan Kunci

Saat membuat atau mengimpor kunci ke dalam AndroidKeyStore Anda bisa menetapkan bahwa kunci hanya diizinkan untuk digunakan jika pengguna telah diautentikasi. Pengguna diautentikasi menggunakan subset dari kredensial layar kunci aman (pola/PIN/sandi, sidik jari).

Ini adalah fitur keamanan canggih yang biasanya berguna hanya jika persyaratan Anda adalah kondisi bahaya dari proses aplikasi setelah kunci dibuat/diimpor (namun tidak sebelum atau selama) tidak dapat mengabaikan persyaratan bagi pengguna agar diautentikasi sebelum bisa menggunakan kunci.

Bila hanya diizinkan untuk digunakan jika pengguna telah diautentikasi, kunci akan dikonfigurasi untuk bekerja dalam salah satu dari dua mode:

  • Autentikasi pengguna mengizinkan penggunaan kunci untuk suatu durasi waktu. Semua kunci di mode ini di-otorisasi untuk digunakan begitu pengguna membuka layar kunci aman atau mengkonfirmasi kredensial layar kunci aman mereka menggunakan alur KeyguardManager.createConfirmDeviceCredentialIntent. Durasi otorisasi tersebut berlaku berbeda untuk setiap kunci, seperti yang ditetapkan menggunakan setUserAuthenticationValidityDurationSeconds selama pembuatan atau impor kunci. Kunci tersebut hanya bisa dibuat atau diimpor jika layar kunci aman diaktifkan (lihat KeyguardManager.isDeviceSecure()). Kunci ini menjadi tidak valid secara permanen setelah layar kunci aman dinonaktifkan (dikonfigurasi ulang ke None, Swipe atau mode lain yang tidak autentikasi pengguna) atau disetel ulang secara paksa (misalnya oleh Administrator Perangkat).
  • Autentikasi pengguna mengizinkan operasi kriptografik tertentu yang terkait dengan salah satu kunci. Dalam mode ini, setiap operasi yang melibatkan kunci tersebut harus secara individual diizinkan oleh pengguna. Saat ini, satu-satunya alat otorisasi tersebut adalah autentikasi sidik jari: FingerprintManager.authenticate. Kunci tersebut hanya bisa dibuat atau diimpor jika setidaknya terdaftar satu sidik jari (lihat FingerprintManager.hasEnrolledFingerprints). Kunci ini menjadi tidak valid secara permanen setelah sidik jari baru didaftarkan atau semua sidik jari dihapus pendaftarannya.

Algoritme yang Didukung

Cipher

Algoritme Didukung (API Level) Catatan
AES/CBC/NoPadding 23+
AES/CBC/PKCS7Padding 23+
AES/CTR/NoPadding 23+
AES/ECB/NoPadding 23+
AES/ECB/PKCS7Padding 23+
AES/GCM/NoPadding 23+ Hanya IV 12-byte yang didukung.
RSA/ECB/NoPadding 18+
RSA/ECB/PKCS1Padding 18+
RSA/ECB/OAEPWithSHA-1AndMGF1Padding 23+
RSA/ECB/OAEPWithSHA-224AndMGF1Padding 23+
RSA/ECB/OAEPWithSHA-256AndMGF1Padding 23+
RSA/ECB/OAEPWithSHA-384AndMGF1Padding 23+
RSA/ECB/OAEPWithSHA-512AndMGF1Padding 23+
RSA/ECB/OAEPPadding 23+

KeyGenerator

Algoritme Didukung (API Level) Catatan
AES 23+ Ukuran yang didukung: 128, 192, 256
HmacSHA1 23+
  • Ukuran yang didukung: 8--1024 (inklusif), harus kelipatan 8
  • Ukuran default: 160
HmacSHA224 23+
  • Ukuran yang didukung: 8--1024 (inklusif), harus kelipatan 8
  • Ukuran default: 224
HmacSHA256 23+
  • Ukuran yang didukung: 8--1024 (inklusif), harus kelipatan 8
  • Ukuran default: 256
HmacSHA384 23+
  • Ukuran yang didukung: 8--1024 (inklusif), harus kelipatan 8
  • Ukuran default: 384
HmacSHA512 23+
  • Ukuran yang didukung: 8--1024 (inklusif), harus kelipatan 8
  • Ukuran default: 512

KeyFactory

Algoritme Didukung (API Level) Catatan
EC 23+ Spesifikasi kunci yang didukung: KeyInfo (hanya kunci privat), ECPublicKeySpec (hanya kunci publik), X509EncodedKeySpec (hanya kunci publik)
RSA 23+ Spesifikasi kunci yang didukung: KeyInfo (hanya kunci privat), RSAPublicKeySpec (hanya kunci publik), X509EncodedKeySpec (hanya kunci publik)

KeyStore

KeyStore mendukung tipe kunci yang sama seperti KeyPairGenerator dan KeyGenerator.

KeyPairGenerator

Algoritme Didukung (API Level) Catatan
DSA 19–22
EC 23+
  • Ukuran yang didukung: 224, 256, 384, 521
  • Kurva nama yang didukung: P-224 (secp224r1), P-256 (aka secp256r1 dan prime256v1), P-384 (aka secp384r1), P-521 (aka secp521r1)

Sebelum API Level 23, kunci EC dapat dibuat dengan menggunakan KeyPairGenerator dari algoritme "RSA" yang diinisialiasi KeyPairGeneratorSpec dengan tipe kunci disetel ke "EC" menggunakan setKeyType(String). Nama kurva EC tidak bisa ditetapkan dengan menggunakan metode ini -- sebuah NIST P-curve akan secara otomatis dipilih berdasarkan ukuran kunci yang diminta.

RSA 18+
  • Ukuran yang didukung: 512, 768, 1024, 2048, 3072, 4096
  • Eksponen publik yang didukung: 3, 65537
  • Eksponen publik default: 65537

Mac

Algoritme Didukung (API Level) Catatan
HmacSHA1 23+
HmacSHA224 23+
HmacSHA256 23+
HmacSHA384 23+
HmacSHA512 23+

Signature

Algoritme Didukung (API Level) Catatan
MD5withRSA 18+
NONEwithECDSA 23+
NONEwithRSA 18+
SHA1withDSA 19–22
SHA1withECDSA 19+
SHA1withRSA 18+
SHA1withRSA/PSS 23+
SHA224withDSA 20–22
SHA224withECDSA 20+
SHA224withRSA 20+
SHA224withRSA/PSS 23+
SHA256withDSA 19–22
SHA256withECDSA 19+
SHA256withRSA 18+
SHA256withRSA/PSS 23+
SHA384withDSA 19–22
SHA384withECDSA 19+
SHA384withRSA 18+
SHA384withRSA/PSS 23+
SHA512withDSA 19–22
SHA512withECDSA 19+
SHA512withRSA 18+
SHA512withRSA/PSS 23+

SecretKeyFactory

Algoritme Didukung (API Level) Catatan
AES 23+ Spesifikasi kunci yang didukung: KeyInfo
HmacSHA1 23+ Spesifikasi kunci yang didukung: KeyInfo
HmacSHA224 23+ Spesifikasi kunci yang didukung: KeyInfo
HmacSHA256 23+ Spesifikasi kunci yang didukung: KeyInfo
HmacSHA384 23+ Spesifikasi kunci yang didukung: KeyInfo
HmacSHA512 23+ Spesifikasi kunci yang didukung: KeyInfo