Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Bekerja lebih aman dengan data Bagian dari Android Jetpack.

Library Keamanan menyediakan implementasi praktik terbaik keamanan yang berkaitan dengan pembacaan dan penulisan data saat dalam penyimpanan, serta pembuatan dan verifikasi kunci.

Library ini menggunakan pola builder untuk menyediakan setelan default yang aman untuk tingkat keamanan berikut:

  • Keamanan kuat yang menyeimbangkan enkripsi yang hebat dengan performa yang baik. Tingkat keamanan ini sesuai untuk aplikasi konsumen, seperti aplikasi perbankan dan chat, serta aplikasi perusahaan yang menjalankan pemeriksaan pembatalan sertifikat.
  • Keamanan maksimum. Tingkat keamanan ini sesuai untuk aplikasi yang memerlukan keystore yang didukung hardware dan kehadiran pengguna untuk memberikan akses kunci.

Panduan ini menunjukkan cara menggunakan konfigurasi keamanan yang direkomendasikan oleh library Keamanan, serta cara membaca dan menulis data terenkripsi yang tersimpan dalam file dan preferensi bersama dengan mudah dan aman.

Pengelolaan kunci

Library Keamanan menggunakan sistem yang terdiri dari 2 bagian untuk pengelolaan kunci:

  • Keyset yang berisi satu atau beberapa kunci untuk mengenkripsi file atau data preferensi bersama. Keyset disimpan di SharedPreferences.

  • Kunci (master) utama yang mengenkripsi semua kumpulan kunci. Kunci ini disimpan menggunakan sistem keystore Android.

Class yang disertakan dalam library

Library Keamanan berisi class berikut untuk menyediakan data yang lebih aman saat dalam penyimpanan:

EncryptedFile

Menyediakan implementasi kustom FileInputStream dan FileOutputStream, yang memberikan aliran operasi baca dan tulis yang lebih aman ke aplikasi Anda.

Untuk memberikan operasi baca dan tulis yang aman dari aliran file, library Keamanan menggunakan primitive Streaming Authenticated Encryption with Associated Data (AEAD). Pelajari primitive ini lebih lanjut dalam dokumentasi library Tink di GitHub.

EncryptedSharedPreferences

Menggabungkan class SharedPreferences dan otomatis mengenkripsi kunci dan nilai menggunakan metode dua skema:

  • Kunci dienkripsi menggunakan algoritme enkripsi deterministik sehingga kunci tersebut dapat dienkripsi dan dicari dengan benar.
  • Nilai dienkripsi menggunakan AES-256 GCM dan bersifat non-deterministik.

Bagian berikut menunjukkan cara menggunakan class ini untuk menjalankan operasi umum dengan file dan preferensi bersama.

Menyertakan library dalam project Anda

Untuk menggunakan library Keamanan, tambahkan dependensi berikut ke file build.gradle modul aplikasi Anda:

dependencies {
    implementation "androidx.security:security-crypto:1.0.0-rc03"

    // For Identity Credential APIs
    implementation "androidx.security:security-identity-credential:1.0.0-alpha01"
}

Membaca file

Cuplikan kode berikut menunjukkan cara menggunakan EncryptedFile untuk membaca konten file dengan cara yang lebih aman:

Kotlin

// Although you can define your own key generation parameter specification, it's
// recommended that you use the value specified here.
val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

val context = applicationContext
val fileToRead = "my_sensitive_data.txt"
val encryptedFile = EncryptedFile.Builder(
    File(DIRECTORY, fileToRead),
    context,
    masterKeyAlias,
    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build()

val inputStream = encryptedFile.openFileInput()
val byteArrayOutputStream = ByteArrayOutputStream()
var nextByte: Int = inputStream.read()
while (nextByte != -1) {
    byteArrayOutputStream.write(nextByte)
    nextByte = inputStream.read()
}

val plaintext: ByteArray = byteArrayOutputStream.toByteArray()

Java

// Although you can define your own key generation parameter specification, it's
// recommended that you use the value specified here.
KeyGenParameterSpec keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC;
String masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec);

Context context = getApplicationContext();
String fileToRead = "my_sensitive_data.txt";
EncryptedFile encryptedFile = new EncryptedFile.Builder(
        new File(DIRECTORY, fileToRead),
        context,
        masterKeyAlias,
        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build();

InputStream inputStream = encryptedFile.openFileInput();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int nextByte = inputStream.read();
while (nextByte != -1) {
    byteArrayOutputStream.write(nextByte);
    nextByte = inputStream.read();
}

byte[] plaintext = byteArrayOutputStream.toByteArray();

Menulis file

Cuplikan kode berikut menunjukkan cara menggunakan EncryptedFile untuk menulis konten file dengan cara yang lebih aman:

Kotlin

// Although you can define your own key generation parameter specification, it's
// recommended that you use the value specified here.
val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

// Creates a file with this name, or replaces an existing file
// that has the same name. Note that the file name cannot contain
// path separators.
val fileToWrite = "my_sensitive_data.txt"
val encryptedFile = EncryptedFile.Builder(
    File(DIRECTORY, fileToWrite),
    context,
    masterKeyAlias,
    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build()

val fileContent = "MY SUPER-SECRET INFORMATION"
        .toByteArray(StandardCharsets.UTF_8)
encryptedFile.openFileOutput().apply {
    write(fileContent)
    flush()
    close()
}

Java

// Although you can define your own key generation parameter specification, it's
// recommended that you use the value specified here.
KeyGenParameterSpec keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC;
String masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec);

// Creates a file with this name, or replaces an existing file
// that has the same name. Note that the file name cannot contain
// path separators.
String fileToWrite = "my_sensitive_data.txt";
EncryptedFile encryptedFile = new EncryptedFile.Builder(
        new File(DIRECTORY, fileToWrite),
        context,
        masterKeyAlias,
        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build();

byte[] fileContent = "MY SUPER-SECRET INFORMATION"
        .getBytes(StandardCharsets.UTF_8);
OutputStream outputStream = encryptedFile.openFileOutput();
outputStream.write(fileContent);
outputStream.flush();
outputStream.close();

Untuk kasus penggunaan yang mengharuskan keamanan tambahan, selesaikan langkah-langkah berikut:

  1. Buat objek KeyGenParameterSpec.Builder, yang meneruskan true ke setUserAuthenticationRequired() dan nilai yang lebih besar dari 0 ke setUserAuthenticationValidityDurationSeconds().
  2. Minta pengguna memasukkan kredensial menggunakan createConfirmDeviceCredentialIntent(). Pelajari lebih lanjut cara meminta autentikasi pengguna untuk penggunaan kunci.

  3. Ganti onActivityResult() untuk mendapatkan callback kredensial yang telah dikonfirmasi.

Untuk informasi lebih lanjut, lihat Mengharuskan autentikasi pengguna untuk penggunaan kunci.

Mengedit preferensi bersama

Cuplikan kode berikut menunjukkan cara menggunakan EncryptedSharedPreferences untuk mengedit kumpulan preferensi bersama yang ditetapkan pengguna dengan cara yang lebih aman:

Kotlin

val sharedPreferences = EncryptedSharedPreferences
    .create(
    FILE_NAME,
    masterKeyAlias,
    context,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

val sharedPrefsEditor = sharedPreferences.edit()

Java

EncryptedSharedPreferences sharedPreferences = EncryptedSharedPreferences
        .create(
                FILE_NAME,
                masterKeyAlias,
                context,
                EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
                EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
        );

SharedPreferences.Editor sharedPrefsEditor = sharedPreferences.edit();