안드로이드

[안드로이드/Android] Migration SharedPreferences to EncryptedSharedPreferences

알통몬_ 2023. 3. 14. 11:56
반응형

의존성추가

implementation("androidx.security:security-crypto:1.0.0")

// 사용 방법
val masterKeyAlias = MasterKey
		.Builder(applicationContext, MasterKey.DEFAULT_MASTER_KEY_ALIAS)
		.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
		.build()

val sharedPref = EncryptedSharePreferences.create(
		context, // Context,
		"encrypted_pref_name", // 파일명
		masterKeyAlias,
		EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, // AES256_SIV으로 key를 암호화
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM // AES256_GCM으로 value를 암호화
)

// Save
val edit = sharedPref.edit()
edit.putString("key", "value")
edit.apply()

// Load
val loadValue = sharedPref.getString("key", "defaultValue")

EncryptedSharedPreferences 사용 전

Android Studio > Device File Explorer > data > data > ‘package name’ > shared_pref

에서 Key, Value 확인 가능

EncryptedSharedPreferences 사용 후

Key, Value 모두 암호화되어 확인할 수 없다.

Migration from SharedPreferences to EncryptedSharedPreferences in Android

package sung.gyun.encryptedsharedpreferencessample

import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey

class SharedPreferenceManager {

    companion object {

        fun getBasicSharedPref(context: Context): SharedPreferences {
            return context.getSharedPreferences(BASIC_PREF_NAME, Context.MODE_PRIVATE)
        }

        fun getEncryptedSharedPref(context: Context): SharedPreferences {

            val masterKeyAlias by lazy {
                MasterKey
                    .Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS)
                    .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
                    .build()
            }
            return EncryptedSharedPreferences.create(
                context,
                ENCRYPTED_PREF_NAME,
                masterKeyAlias,
                EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, // AES256_SIV으로 key를 암호화
                EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM // AES256_GCM으로 value를 암호화
            )
        }

        fun migrate(context: Context) {
            with(getBasicSharedPref(context)) {
                if(this.all.isNotEmpty()) {
                    copyTo(context, this)
                }
            }
        }

        private fun copyTo(context: Context, sharedPreferences: SharedPreferences) {
            val editor = getEncryptedSharedPref(context).edit()
            val keys = sharedPreferences.all
            for(entry in keys.entries) {
                val key = entry.key
                val value = entry.value
                Log.d("map values", "$key: $value")
                if(value is Int) {
                    editor.putInt(key, value).apply()
                    sharedPreferences.edit().remove(key).apply()
                }
                if(value is Boolean) {
                    editor.putBoolean(key, value).apply()
                    sharedPreferences.edit().remove(key).apply()
                }
                if(value is Long) {
                    editor.putLong(key, value).apply()
                    sharedPreferences.edit().remove(key).apply()
                }
                if(value is Float) {
                    editor.putFloat(key, value).apply()
                    sharedPreferences.edit().remove(key).apply()
                }
                if(value is String) {
                    editor.putString(key, value).apply()
                    sharedPreferences.edit().remove(key).apply()
                }
            }
        }

        private const val BASIC_PREF_NAME = "basic_pref_name"
        private const val ENCRYPTED_PREF_NAME = "encrypted_pref_name"
    }

}

 

예제 소스코드

https://github.com/Parksunggyun/EncryptedSharedPreferencesSample

 

 

반응형