Android

[Android] EncryptedSharedPreferences 사용해보기

Xmobile 2020. 10. 20. 17:39

기존에 SharedPreferences에서 저장시 plain text인 것을  EncryptedSharedPreferences를 이용하면 암호화되어 저장하는 기능을 제공합니다. 

 

자세한 내용은 

https://developer.android.com/topic/security/data?hl=ko

 

Android 개발자  |  Android Developers

더 안전하게 데이터 사용 Android Jetpack의 일부 보안 라이브러리는 저장 데이터 읽기 및 쓰기와 관련된 보안 권장사항의 구현과 키 생성 및 인증을 제공합니다. 라이브러리는 빌더 패턴을 사용하��

developer.android.com

Android 6.0(API 수준 23) 이상을 실행하는 기기에서 지원됩니다

 

 

App내에 ID, PASSWORD와 같은 중요정보를 AES 대칭키(암호화, 복호화 키 동일)를 이용하여  암호화를 했을때 문제점은 

키 관리였습니다.

프로젝트내에 하드코딩된 문자열은 보안상 취약하므로 노출의 위험이 있습니다.

 

EncryptedSharedPreferences를 이용하여 저장해 보도록 하겠습니다.

라이브러리 내부적으로 KeyStore를 이용하여 키 접근은 application레벨에서 접근이 안되어 안전하다고 볼 수 있습니다. 

https://developer.android.com/training/articles/keystore?hl=ko

 

Android Keystore 시스템  |  Android 개발자  |  Android Developers

Android Keystore 시스템을 사용하면 암호화 키를 컨테이너에 저장하여 기기에서 키를 추출하기 어렵게 할 수 있습니다. 키 저장소에 키가 저장되면, 키 자료는 내보낼 수 없는 상태로 유지하면서 키

developer.android.com

gradle

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

 

테스트 코드

val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

val SharedPreferences = EncryptedSharedPreferences
        .create(
            "android",
            masterKeyAlias,
            requireContext(),
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
        )

val sharedPrefsEditor = SharedPreferences.edit()
sharedPrefsEditor?.apply {
    putString("id", "test")
    putString("password", "test")
}
sharedPrefsEditor.apply()

Log.d(TAG, SharedPreferences.getString("id", "not found").toString())

 

확인 XML 열어보기

/data/data/[packageName]/shared_prefs/android.xml 

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a90115c36d71e8bd3b39a8409886b09616e196b34e6df40b5a585f7223e34216ff542cb59dcd2759720826c95dad26a36aa7ce081d9e4eeddc9bc1aee8f1fb2cb473bf3d2acfb459e12cb760661372c8322e682cc7b5982ef9fccd6a9699643d75eca2b63adbaf166f5537cddded9c8b1c3daa0a8d7c68d88f292d9804b270878e281fb654ab77b40248725b91046cba9885af649384766684316b6be6813f351f7fb214391ba6c8d0a6fb1a44089cdaf29501123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b65791001189cdaf295012001</string>
    <string name="ARK8rRzpTKbecLHO3yCiMMBaFHa2xCLZAJhtLVE=">ASyO+WIJmBqi+YFJPHKfX8DDLv8bZfqjVrL59TgD3CVmAfLH9elUqE+8hmVA</string>
    <string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">128801c62e98509808338085528011581576775e3701e7483e4a9d27b89ba63e3406db1b8a6a71d9aee723173fe3feb24455eb6ddbc5ffcab51dc7b4e6b4dc831a4e3daf4f2e3612337734667cfd134949655e2d05623badf75f5cde42eb4148d6aed4edd5914779e0ee360c905c0ffa3192c11d8560bc78c5bc4d84ff651bfca54ba67c5786059ae4f1701a4408e2f2bbe402123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b6579100118e2f2bbe4022001</string>
    <string name="ARK8rRxdjEShL1rCHntSr1uL6GEkhB4=">ASyO+WKJ42K6D7TXNXO5Os3dxLGmJeGdlYVsIRYUVif85iONYyTlSkwWhzQl</string>
</map>

위와같이 암호화되어 저장되어 있는것을 확인하였습니다.