Bagaimana cara menyimpan token akses dan rahasia dengan aman di Android?

123

Saya akan menggunakan oAuth untuk mengambil email dan kontak dari google. Saya tidak ingin meminta pengguna setiap kali masuk untuk mendapatkan token akses dan rahasia. Dari apa yang saya pahami, saya perlu menyimpannya dengan aplikasi saya baik dalam database atau SharedPreferences. Tapi saya agak khawatir tentang aspek keamanan dengan itu. Saya membaca bahwa Anda dapat mengenkripsi dan mendekripsi token tetapi mudah bagi penyerang untuk hanya mendekompilasi apk dan kelas Anda dan mendapatkan kunci enkripsi.
Apa metode terbaik untuk menyimpan token ini dengan aman di Android?

ya bung
sumber
1
Bagaimana cara menyimpan kunci dan rahasia konsumen (hardconding tidak diamankan)? saya membutuhkan mereka untuk meminta akses dan rahasia .. bagaimana aplikasi lain yang sudah ada yang menggunakan oAuth melakukannya? hmm akhirnya dengan oauth, Anda perlu mengurus lebih banyak masalah keamanan untuk saya .... saya perlu menjaga token / rahasia konsumen dengan aman dan juga akses dan rahasia .... akhirnya bukankah itu lebih mudah untuk simpan saja nama pengguna / kata sandi pengguna yang dienkripsi? ... pada akhirnya, bukankah yang terakhir lebih baik? Aku masih tidak bisa melihat bagaimana oauth lebih baik ...
yeahman
dapatkah Anda memberi tahu saya..file mana yang menyimpan token akses ?? Saya baru mengenal Android dan saya mencoba menjalankan aplikasi sampel Plus. Tapi saya tidak menemukan ini di mana pun [GoogleAuthUtil.getToken () metode.]
Abhishek Kaushik

Jawaban:

117

Simpan sebagai preferensi bersama . Itu secara default pribadi, dan aplikasi lain tidak dapat mengaksesnya. Pada perangkat yang di-rooting, jika pengguna secara eksplisit mengizinkan akses ke beberapa aplikasi yang mencoba membacanya, aplikasi tersebut mungkin dapat menggunakannya, tetapi Anda tidak dapat melindunginya. Sedangkan untuk enkripsi, Anda harus meminta pengguna untuk memasukkan frasa sandi dekripsi setiap kali (sehingga mengalahkan tujuan kredensial caching), atau menyimpan kunci ke file, dan Anda mendapatkan masalah yang sama.

Ada beberapa keuntungan menyimpan token selain kata sandi nama pengguna yang sebenarnya:

  • Aplikasi pihak ketiga tidak perlu mengetahui kata sandinya dan pengguna dapat yakin bahwa mereka hanya mengirimkannya ke situs asli (Facebook, Twitter, Gmail, dll.)
  • Bahkan jika seseorang mencuri token, mereka tidak dapat melihat sandi (yang mungkin juga digunakan pengguna di situs lain)
  • Token umumnya memiliki masa pakai dan kedaluwarsa setelah waktu tertentu
  • Token dapat dicabut jika Anda mencurigai mereka telah disusupi
Nikolay Elenkov
sumber
1
terima kasih atas jawabannya! tapi bagaimana saya bisa tahu jika kunci konsumen saya telah disusupi? lol akan sulit untuk mengatakannya .. ok tentang menyimpan token akses dan rahasia, ok saya menyimpannya di sharedpreferences dan mengenkripsi mereka tetapi bagaimana dengan kunci dan rahasia konsumen? Saya tidak dapat menyimpannya di sharedpreferences (saya perlu secara eksplisit menulis kunci dan rahasia konsumen dalam kode untuk menyimpannya di sharedpreference di tempat pertama) .. tidak tahu apakah Anda mengerti apa yang saya maksud.
yeahman
2
Anda harus menempatkan aplikasi di dalam aplikasi dengan cara yang (agak) dikaburkan, agar aplikasi tidak segera terlihat setelah dekompilasi, atau menggunakan aplikasi web proxy authrorization Anda sendiri yang memiliki kunci dan rahasia. Menempatkannya dalam aplikasi jelas lebih mudah, dan jika menurut Anda risiko seseorang yang mencoba memecahkan aplikasi Anda cukup rendah, lakukan pendekatan itu. BTW, poin di atas adalah untuk kata sandi pengguna. Jika Anda mengetahui kunci / rahasia konsumen Anda telah disusupi, Anda juga dapat mencabutnya (hal itu, tentu saja, akan merusak aplikasi Anda).
Nikolay Elenkov
1
@NikolayElenkov: Anda menulis 'Mengenai enkripsi, Anda harus meminta pengguna untuk memasukkan frasa sandi dekripsi setiap saat (dengan demikian mengalahkan tujuan kredensial cache), atau menyimpan kunci ke file, dan Anda mendapatkan masalah yang sama.' . Bagaimana jika cracker membalik aplikasi Anda untuk mendapatkan wawasan tentang cara kerja enkripsi? Pertahanan Anda mungkin rusak. Apakah praktik terbaik untuk menyimpan informasi semacam itu (token, enkripsi ...) menggunakan kode asli?
anhldbk
1
Jika data aplikasi dihapus, token penyegaran hilang, yang mungkin bukan yang diinginkan pengguna.
rds
1
Ini bukan lagi cara terbaik untuk menyimpan token sekarang-a-hari!
Rahul Rastogi
19

Anda dapat menyimpannya di AccountManager . Itu dianggap praktik terbaik menurut orang-orang ini.

masukkan deskripsi gambar di sini

Berikut definisi resminya:

Kelas ini menyediakan akses ke registri terpusat dari akun online pengguna. Pengguna memasukkan kredensial (nama pengguna dan sandi) satu kali per akun, memberikan aplikasi akses ke sumber daya online dengan persetujuan "sekali klik".

Untuk panduan mendetail tentang cara menggunakan AccountManager:

Namun, pada akhirnya AccountManager hanya menyimpan token Anda sebagai teks biasa. Jadi, saya sarankan mengenkripsi rahasia Anda sebelum menyimpannya di AccountManager. Anda dapat memanfaatkan berbagai pustaka Enkripsi seperti AESCrypt atau AESCrypto

Pilihan lainnya adalah dengan menggunakan perpustakaan Tersembunyi . Cukup aman untuk Facebook dan jauh lebih mudah digunakan daripada AccountManager. Berikut potongan kode untuk menyimpan file rahasia menggunakan Conceal.

byte[] cipherText = crypto.encrypt(plainText);
byte[] plainText = crypto.decrypt(cipherText);
aldok
sumber
2
Tip bagus itu Conceal. Terlihat sangat mudah digunakan. Dan untuk banyak kasus penggunaan.
lagos
Tidak dapat menemukan Conceal melalui tautan. Ini mungkin dinonaktifkan
pengguna1114
10

SharedPreferences bukanlah lokasi yang aman. Pada perangkat yang di-rooting, kami dengan mudah dapat membaca dan memodifikasi semua aplikasi 'SharedPrefereces xml's. Jadi token harus sering kedaluwarsa. Tetapi meskipun token kedaluwarsa setiap jam, token yang lebih baru masih dapat dicuri dari SharedPreferences. Android KeyStore harus digunakan untuk penyimpanan jangka panjang dan pengambilan kunci kriptografi yang akan digunakan untuk mengenkripsi token kami untuk menyimpannya di misalnya SharedPreferences atau database. Kunci tidak disimpan dalam proses aplikasi, jadi lebih sulit untuk disusupi.

Jadi yang lebih relevan daripada sebuah tempat adalah bagaimana mereka dapat mengamankan dirinya sendiri misalnya menggunakan JWT berumur pendek yang ditandatangani secara kriptografis, mengenkripsi mereka menggunakan Android KeyStore dan mengirimkannya dengan protokol yang aman

puncak39
sumber
9
Lalu dimana kita bisa menyimpannya?
Milind Mevada
2
  1. Dari panel Project Android Studio Anda, pilih "Project Files" dan buat file baru bernama "keystore.properties" di direktori root project Anda.

masukkan deskripsi gambar di sini

  1. Buka file "keystore.properties" dan simpan Access Token and Secret Anda di file tersebut.

masukkan deskripsi gambar di sini

  1. Sekarang muat bacaan Access Token and Secret di file build.gradle modul aplikasi Anda . Kemudian Anda perlu menentukan variabel BuildConfig untuk Access Token dan Secret sehingga Anda dapat langsung mengaksesnya dari kode Anda. Build.gradle Anda mungkin terlihat seperti berikut:

    ... ... ... 
    
    android {
        compileSdkVersion 26
    
        // Load values from keystore.properties file
        def keystorePropertiesFile = rootProject.file("keystore.properties")
        def keystoreProperties = new Properties()
        keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    
        defaultConfig {
            applicationId "com.yourdomain.appname"
            minSdkVersion 16
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    
            // Create BuildConfig variables
            buildConfigField "String", "ACCESS_TOKEN", keystoreProperties["ACCESS_TOKEN"]
            buildConfigField "String", "SECRET", keystoreProperties["SECRET"]
        }
    }
  2. Anda dapat menggunakan Access Token and Secret dalam kode Anda seperti ini:

    String accessToken = BuildConfig.ACCESS_TOKEN;
    String secret = BuildConfig.SECRET;

Dengan cara ini Anda tidak perlu menyimpan Access Token dan Secret dalam teks biasa di dalam proyek Anda. Jadi, meskipun seseorang mendekompilasi APK Anda, mereka tidak akan pernah mendapatkan Token Akses dan Rahasia Anda saat Anda memuatnya dari file eksternal.

Zahidur Rahman Faisal
sumber
1
Sepertinya tidak ada perbedaan membuat file properti sebagai pengganti hard coding.
Dzshean
Saya ingin menulis Token saat menjalankan mungkin token saya setiap kali berubah ketika saya membuka aplikasi saya.
Rehan Sarwar
1
Ini cara yang sangat bagus untuk menyimpan beberapa token seperti token akses API. jika Anda ingin menyimpan kredensial pengguna, NDK adalah cara yang lebih baik.
Eric
7
Ini sama sekali bukan bagaimana Anda harus menyimpan informasi sensitif dalam aplikasi Anda! Meskipun repositori tidak berisi data dengan menggunakan pendekatan ini (data dimasukkan ke dalam proses build), ini menghasilkan file BuildConfig yang memiliki token / rahasia dalam teks biasa untuk dilihat semua orang setelah dekompilasi sederhana.
Hrafn
-1

Nah, Anda dapat mengamankan token akses Anda dengan mengikuti dua opsi.

  1. Gunakan simpan token akses Anda ke keystore android yang tidak akan terbalik.
  2. Gunakan fungsi NDK dengan beberapa penghitungan yang menyimpan token Anda dan NDK dengan kode c ++ yang sangat sulit untuk dibalik
M. Noman
sumber