비교적 간단한 데이터를 저장하기위해 안드로이드 개발 시 SharedPreferences를 사용한다.
설정에 따라서 SharedPreferences 파일은 프레임워크에서 관리하며 비공개이거나 공개로 설정할 수 있다.
비공개로 설정할 경우 일반적인 방법으로는 저장된 데이터를 확인할수는 없지만, 루팅을 통해 관리자 권한을 획득한 경우 저장된 데이터를 확인할 수있다. 개인정보(카드번호, 인증 비밀번호) 등 중요한 데이터가 저장하여야 하는경우에는 SharedPreferences는 적합하지 않다.
Android SDK 23부터 androidx.security를 통해 EncryptedSharedPreferences를 제공한다.
https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences
기본적인 사용방법은
MasterKey masterKey = new MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build();
_sharedPreferences = EncryptedSharedPreferences.create(
context,
"secret_shared_pref",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
AES256방식에 암호화 키를 생성하여 생성한 암호화 키로 저장되는 데이터의 AES256_SIV(key) ,AES256_GCM (data)방식으로 키와 데이터를 각각 암호화한다.
(암호화 키 생성 시 keystore를 사용하기 때문에 별도의 키입력을 하지 않으며, 생성된 암호화 키는 컨테이너에 저장되어 저장된 암호화키는 외부에서 추출하기 어렵다.)
https://developer.android.com/training/articles/keystore?hl=ko
SharedPreferences와 동일하게 앱 삭제 시 저장된 데이터도 함꼐 삭제되며, 저장된 데이터는 아래와 같이 암호화되어 저장된다.
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a90125a94b1b6aa4f97a630764baecf0e5f4c046a82c8b7947dabc06e71c5170a654d27c1903ffe2da75f84fd1dd011f37c917e9b8ce21d6b4673bbec9127ea066e6adb177f34bc98ff7259331f0d854b78d318226ed62dca1b38ec2dd32598a9357432e0e524a91e9a27393370337acbc5611f8808a6d8bcb724506dcb0e5513e6d6c0cb93d9af1f22cde840c93f3c213adce4bf1cd38aea6464724a1f0bf0bc7153ea84df9b5f4f4344b1a4408b191c8fc03123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b6579100118b191c8fc032001</string>
<string name="AT+SCLGWnuSnzmogArPsMQJbMe92S7STOQ==">AR4mc1e8vYohj66Q91oCIoaMmklTD+DDPStaqibMtsDXatXDJJeskjW7eW9WNTGR</string>
<string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">128801163831f1d036fdc9a33da123fee29b5cda21a49d89684f5fac67e3d54a634de5d8ca990106d0535f0ce74e824f8352e027a37a7512a189a67c183781bf6ce08894b3a622bda2632205c5e5f64389cbff75556bd05d0f8dcd8dc495b9cff09681a7e1e18bae625b7d1513e7301c4ed2aa1e592b97df72474ee9437f75e20e1a019803d7cb3cd9f78f1a4408d7e699f101123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b6579100118d7e699f1012001</string>
<string name="AT+SCLEaHEykuXI9WqXm7wB0ZOTyX/dPWI4=">AR4mc1euqAo6fPFARiDB0ACt92fHt3w1P+64D76rk9Dlyv4ya/hKWgQ5dHy6COIN</string>
</map>
EncryptedSharedPreferences 을 사용하기 위해서는 Security 라이브러리를 추가 해야함.
(build.gradle의 dependencies추가)
implementation "androidx.security:security-crypto-ktx:1.1.0-alpha03"
EncryptedSharedPreferences 공통 Class로 사용하기 위한 샘플 소스
import android.content.Context;
import android.content.SharedPreferences;
import androidx.security.crypto.EncryptedSharedPreferences;
import androidx.security.crypto.MasterKey;
import java.io.IOException;
import java.security.GeneralSecurityException;
public class SharedPreferenceUtil {
private static SharedPreferenceUtil sharedInstance;
private Context _context = null;
private MasterKey masterKey = null;
private SharedPreferences _sharedPreferences = null;
private SharedPreferences.Editor _shEditor = null;
private final static String SECRET_PREFERENCE = "secret_shared_prefs";
public static synchronized SharedPreferenceUtil getInstance(Context context) throws GeneralSecurityException, IOException {
if (null == sharedInstance) {
sharedInstance = new SharedPreferenceUtil(context);
}
return sharedInstance;
}
public SharedPreferenceUtil(Context context) throws GeneralSecurityException, IOException {
MasterKey masterKey = new MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build();
_sharedPreferences = EncryptedSharedPreferences.create(
context,
SECRET_PREFERENCE,
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
}
public void putString(String key, String data) {
_shEditor.putString(key, data);
_shEditor.commit();
}
public void putInt(String key, int data) {
_shEditor.putInt(key, data);
_shEditor.commit();
}
public void putFloat(String key, float data) {
_shEditor.putFloat(key, data);
_shEditor.commit();
}
public void putLong(String key, long data) {
_shEditor.putLong(key, data);
_shEditor.commit();
}
public void putBoolean(String key, boolean data) {
_shEditor.putBoolean(key, data);
_shEditor.commit();
}
public void clear() {
if (null != _shEditor) {
_shEditor.clear();
_shEditor.commit();
}
}
public String getString(String key, String defValue) {
return _sharedPreferences.getString(key, defValue);
}
public int getInt(String key, int defValue) {
return _sharedPreferences.getInt(key, defValue);
}
public float getFloat(String key, float defValue) {
return _sharedPreferences.getFloat(key, defValue);
}
public long getLong(String key, long defValue) {
return _sharedPreferences.getLong(key, defValue);
}
public boolean getBoolean(String key, boolean defValue) {
return _sharedPreferences.getBoolean(key, defValue);
}
}
'Android' 카테고리의 다른 글
[안드로이드] kotlin uuid 생성코드 (1) | 2024.09.10 |
---|---|
[안드로이드] 에뮬레이터 네트워킹(localhost 테스트) (0) | 2022.12.19 |
[안드로이드] TextClock 사용법 (0) | 2022.12.02 |
[안드로이드] Execution failed for task ':app:validateSigningDebug' 오류(debug.keystore not found ) (0) | 2022.11.29 |
[안드로이드] React-Native Error: error:0308010C:digital envelope routines::unsupported (0) | 2022.11.29 |