Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Security
Code

Keys, Credentials dan Storage pada Android

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Imam Firmansyah (you can also view the original English article)

Pada postingan sebelumnya tentang keamanan data pengguna Android, kita melihat pada proses enkripsi data melewati user-supplied passcode. Pada tutorial ini akan memfokuskan pada credential dan key storage. Saya akan memulai dengan memperkenalkan account credential dan diakhiri dengan mengamankan data menggunakan KeyStore.

Sering, ketika bekerja dengan third-party service, akan terdapat beberapa bentuk dari autentikasi yang diperlukan.  Ini akan terlihat sederhana seperti /login pada titik akhir yang menerima username dan password.

Itu akan terlihat sesuatu bahwa solusi yang sederhana untuk membangun UI yang meminta user untuk login dan kemudian mengambil dan menyimpan login credential mereka.  Namun, ini bukan cara yang baik karena aplikasi kita tidak perlu tahu credential dari akun third-party. Tapi, kita dapat menggunakan Account Manager, dimana akan melimpahkan informasi sensitf pada kita.

Account Manager

Account Manager merupakan suatu helper yang terpusat untuk user account credential jadi aplikasi Anda tidak perlu untuk menangani banyak password secara langsung. Ini biasanya akan menyiapkan sebuah token pada tempat dimana username dan password yang asli dapat digunakan untuk membuat suatu permintaan autentikasi untuk sebuah service. Sebagai contoh adalah ketika meminta request beberapa OAuth2 token.

Terkadang, semua informasi yang dibutuhkan sudah tersimpan pada suatu perangkat, dan pada kesempatan lain suatu Account Manager akan membutuhkan panggilan sebuah server untuk mendapatkan token yang baru.  Anda mungkin sudah melihat bagian Akun pada suatu pengaturan perangkat untuk berbagai macam aplikasi.  Kita dapat mengambil semua daftar yang tersedia pada akun seperti ini:

Code ini akan membutuhkan izin android.permission.GET_ACCOUNTS. Jika Anda mencari suatu akun yang spesifik, Anda bisa mencarinya seperti ini:

Ketika Anda telah mendapatkan akun tersebut, sebuah token untuk akun bisa diambil dengan cara memanggil metohod getAuthToken(Account, String, Bundle, Activity, AccountManagerCallback, Handler). Token kemudian bisa digunakan untuk membuat autentikasi API requests ke suatu service.  Ini bisa jadi adalah sebuah RESTful API dimana Anda bisa menyampaikan pada parameter token ketika dilakukan HTTPS request, tanpa sama sekali untuk mengetahui detail dari akun pribadi pengguna

Karena setiap service akan mempunyai cara yang berbeda untuk melakukan autentikasi dan menyimpan suatu private credentials, Account Manager menyediakan authenticator module untuk third-party service untuk di implementasi. Ketika Android telah melakukan implementasi untuk banyak service yang popular, ini berarti Anda dapat menulis authenticator Anda sendiri untuk menangani account authentication untuk aplikasi Anda dan tempat penyimpanan credential. Ini memungkinkan Anda untuk memastikan credentialnya ter-enkripsi. Yang harus diingat, Ini juga berarti credential pada Account Manager digunakan untuk service lain yang mungkin disimpan dalam teks asli, membuat mereka mudah dilihat oleh siapapun yang telah melakukan root pada perangkatnya.

Dari pada credential yang sederhana, ada waktunya ketika Anda membutuhkan suatu kunci atau sertifikat untuk individual atau suatu kelompok, sebagai contoh, ketika suatu third-party mengirimkan Anda sebuah file sertifikat yang Anda harus simpan. Skenario yang paling umum adalah ketika suatu aplikasi membutuhkan autentikasi untuk private organization’s server.

Pada tutorial selanjutnya, kita akan melihat cara menggunakan sertifikat untuk autentikasi dan mengamankan suatu komunikasi, tapi saya akan mengingatkan bagaimana cara menyimpan item ini pada sementara waktu. Pada dasarnya Keychain API dibuat untuk sesuatu yang spesifik, melakukan install private key atau pasangan sertifikat dari sebuah PKCS#12 file.

Keychain

Diperkenalkan pada Android 4.0(API level 14), Keychain API terlibat dengan key management. Secara spesifik, itu dapat bekerja dengan PrivateKey dan X509Certificate objek dan menyediakan container yang lebih aman daripada menggunakan penyimpanan data aplikasi Anda. Itu karena izin untuk sebuah private key hanya memperbolehkan untuk aplikasi Anda, dan hanya setelah dilakukan autorisasi. Ini berarti suatu layar kunci harus di siapkan sebelum mengakses sebuah penyimpanan credential. Juga, objek di Keychain mungkin terikat pada secure hardware, jika tersedia.

Code ini akan meng-install sebuah sertifikat seperti:

Pengguna akan diminta sebuah password untuk mengakses private key dan pilihan untuk nama sertifikat. Untuk mengambil kunci, kode berikut menyajikan UI yang memperbolehkan user untuk memilih daftar dari kunci yang sudah terinstall.

Ketika sudah membuat pilihan, sebuah string atau nama di tampilkan pada sebuah alias(final String alias) dimana Anda bisa mengakses private key atau rantai sertifikat secara langsung.

Dengan memiliki pengetahuan tersebut, mari kita melihat bagaimana kita menggunakan penyimpanan credential untuk menyimpan data sensitif Anda.

KeyStore

Pada tutorial sebelumnya, kita melihat proses melindungi data menggunakan user-supplied passcode. Cara seperti ini bagus, tetapi kebutuhan suatu aplikasi biasanya menjauhi user untuk melakukan log in setiap waktu dan mengingat suatu passcode tambahan.

Itulah dimana KeyStore API bisa digunakan. Sejak API 1, KeyStore telah digunakan oleh sistem untuk menyimpan Wifi dan VPN credential. Seperti 4.3 (API 18), memungkinkan Anda untuk bekerja dengan app-specific asymmetric keys Anda sendiri, dan pada Android M (API 23) itu bisa menyimpan AES symmetric key. Jadi ketika API tidak memperbolehkan untuk menyimpan data sensitif secara langsung, kunci ini bisa disimpan dan kemudian digunakan untuk mengenkripsi kalimat.

Keunggulan dari menyimpan suatu kunci di KeyStore itu adalah memperbolehkan kunci untuk dioperasikan tanpa mengekspos konten rahasia dari si kunci; data kunci tidak masuk pada penyimpanan aplikasi. Ingat bahwa kunci diamankan menggunakan izin jadi hanya aplikasi Anda yang dapat mengakses mereka, dan mereka juga dapat menggunakan perangkat keras yang didukung jika perangkat tersebut mendukung. Ini membuat container lebih sulit untuk di ekstrak dari perangkat.

Menghasilkan sebuah Random Key Baru

Sebagai contoh, daripada menghasilkan kunci AES dari user-supplied passcode, kita bisa menghasilkan kunci acak secara otomatis yang akan diamankan di KeyStore. Kita bisa melakukan ini dengan membuat KeyGenerator instance, siapkan untuk "AndroidKeyStore" provider.

Bagian penting yang perlu dilihat disini adalah .setUserAuthenticationRequired(true) dan spesifikasi .setUserAuthenticationValidityDurationSeconds(120). Ini dibutuhkan untuk mengunci layar yang di siapkan dan akan terkunci sampai user ter-autentikasi.

Melihat dari dokumentasi untuk .setUserAuthenticationValidityDurationSeconds(), Anda berarti akan melihat kunci hanya tersedia beberapa detik dari suatu autentikasi password, dan dikirim pada -1 yang dibutuhkan untuk fingerprint authentication setiap kali Anda ingin mengakses kunci. Memungkinkan kebutuhan untuk autentikasi juga memilki efek untuk menolak kunci ketika user menghapus atau mengubah kunci pada layar.

Karena menyimpan sesuatu yang tidak terlindungi bersamaan dengan data yang terenkripsi seperti menaruh kunci rumah dibawah keset, pilihan ini mencoba untuk mengamankan kunci di setiap kegiatan yang ada pada perangkat. Sebagai contoh seperti offline data dump dari suatu perangkat. Tanpa sebuah password yang diketahui untuk sebuah perangkat, data yang dirender tidaklah berguna.

Pengaturan .setRandomizedEncryptionRequired(true) memungkinkan kebutuhan yang cukup untuk melakukan sesuatu secara acak (sebuah random IV setiap saat) jadi jika data yang sama terenkripsi setiap detik, hasil enkripsi akan tetap berbeda. Ini akan mencegah penyerang untuk mendapatkan sebuah petunjuk tentang ciphertext dari data yang sama.

Pengaturan yang lain yang perlu dicatat adalah setUserAuthenticationValidWhileOnBody(boolean remainsValid), yang mengunci sebuah kunci ketika perangkat terdeteksi tidak pada pemilik yang asli.

Mengenkripsi Data

Sekarang kunci tersebut disimpan di KeyStore, kita bisa membuat method yang mengenkripsi data menggunakan Cipher object, yang diberikan SecretKey. Itu akan membalikan sebuah HashMap yang mengandung data terenkripsi dan sebuah randomize IV yang akan dibutuhkan untuk mendekripsi data. Enkripsi data, bersama dengan IV, bisa kemudian disimpan pada sebuah file atau pada shared preferences.

Mendekripsi ke Byte Array

Untuk mendekripsi, suatu reverse diperlukan. Cipher object di inisialisasi menggunakan konstan DECRYPT_MODE, dan sebuah dekripsi byte[] array yang akan dikembalikan.

Menguji Contoh

Sekarang kita dapat mencoba sebuah contoh!

Menggunakan RSA Asymmetric Keys untuk Perangkat yang Lama

Ini adalah solusi yang bagus untuk menyimpan data dari versi M dan lebih tinggi, tapi bagaimana jika aplikasi Anda mendukung versi sebelumnya? Sementara kunci AES symmetric tidak mendukung dibawah M, RSA asymmetric keys. Itu berarti kita bisa menggunakan RSA keys dan enkripsi untuk mendapatkan sesuatu yang sama.

Perbedaan utama disini adalah asymmetric keypair mengandung dua kunci, private dan public key, dimana public key mengenkripsi data dan private key mendeskripsinya. Sebuah KeyPairGeneratorSpec dikirim ke KeyPairGenerator yang di inisialisai dengan KEY_ALGORITHM_RSA dan "AndroidKeyStore" provider.

Untuk mengenkripsi, kita mengambil RSAPublicKey dari Keypair dan menggunakannya dengan Cipher object.

Dekripsi dilakukan dengan menggunakan objek RSAPrivateKey.

Satu hal tentang RSA adalah enkripsi lebih lambat dari AES. Ini tidak apa-apa untuk data yang jumlahnya sedikit, seperti mengamankan shared preference strings. Jika Anda menemukan masalah performa mengenkripsi sebuah data, namun, Anda bisa menggunakan contoh ini untuk mengenkripsi dan menyimpannya sama seperti AES key. Kemudian, gunakan enkripsi AES yang lebih cepat yang telah kita diskusikan pada tutorial sebelumnya untuk sisa data Anda. Anda bisa membuat AES key baru dan mengubahnya menjadi byte[] array yang cocok seperti contoh berikut.

Untuk mendapatkan key kembali dari bytes, lakukan ini:

Ada banyak sekali kode! Untuk membuat semua contoh mudah, saya telah menghilangkan secara menyeluruh exception handling. Tapi yang perlu diingat adalah produksi dari kode Anda, ini tidak di rekomendasikan untuk mengambil semua Throwable cases pada satu statement.

Kesimpulan

Ini melengkapi tutorial tentang bekerja pada credential dan keys. Sangat membingunkan pada keys dan storage karena evolusi pada Android OS, tetapi Anda bisa memilih solusi dari API level yang aplikasi Anda dukung.

Sekarang kita sudah mencakup cara terbaik untuk mengamankan data seluruhnya, tutorial berikutnya akan fokus pada mengamankan data di transit.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.