ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [안드로이드 JAVA] SharedPreferences 암호화하기 (androidx.security 이용)
    Programming/Android 2021. 2. 13. 19:31

    안드로이드 앱 개발을 할 때,

    사용자 입력 값을 저장하는 방법은 임의의 파일을 생성하거나 SQLite에 저장하는 방법 등 다양한 방법이 있다.

    그러나 간단하게 1~2개의 데이터를 사용하기 위해 복잡한 파일을 만들거나 SQLite를 사용하기보다

    SharedPreferences를 사용하는 것이 좀 더 편리하다.

     

    SharedPreferences는 기본값으로 xml파일을 생성하고 그 위치는 다음과 같다.

    /data/data/{package_name}/shared_prefs/filename.xml

     

    사용방법도 몇 줄 되지 않아 간단히 사용할 수 있다.

    SharedPreferences sharedPreferences = getSharedPreferences("filename", this.MODE_PRIVATE);
    SharedPreferences.Editor spfEditor = sharedPreferences.edit();
    spfEditor.putString("name", "value");
    spfEditor.commit();

     

    코드를 실행하면 해당 위치에 filename.xml 파일이 생성된다.

    xml 파일을 열어보면 putString에 기재한 값이 저장되어 있는 것을 확인할 수 있다.

    <map>
        <string name="name">value</string>
    </map>

     

    그러나,

    SharedPreferences를 사용하면 위와 같이 단순 평문으로 내용이 저장되기 때문에,

    큰 의미없는 사용자의 입력값이라면 모르겠지만, 아이디나 연락처와 같은 사용자의 개인정보라면 대단히 위험한 상황이다.

    누군가 사용자의 폰을 이용하여 해당값을 아주 쉽게 유출하여 악용할 수 있기 때문이다.

     

    위와 같은 일을 방지하기 위해서는

    AES나 SHA와 같은 암호화를 위한 다양한 외부 암호화 라이브러리를 사용하면 된다.

    하지만, 단순하게 1~2개의 데이터 때문에 외부 라이브러리를 사용하기에는 좀 부담이 되는 상황이다.

     

    다행히,

    Android SDK 23 (마시멜로 6.0) 부터 androidx.security 를 통하여

    SharedPreferences에서도 아주 간단하게 암호화를 할 수 있게 되었다.

     

    바로, EncryptedSharedPreferences 이다.

     

    EncryptedSharedPreferences  |  Android Developers

    androidx.wear.watchface.complications.rendering

    developer.android.com

     

    이를 사용하기 위해서는 build.gradle에 androidx.security 를 추가하여야 한다.

    build.gradle에 직접 기입하여도 되지만, 다음과 같이 추가하는 것을 권장한다.

     

    File > Project Structure > Dependencies > app > Declared Dependencies [+] > Library Dependency

     

    Add Library Dependency 창이 열리면,

    androidx.secu* 로 검색하여 androidx.security 중 security-crypto 최신 버전을 설치하면 된다.

     

     

    androidx.security:security-crypto 가 추가한 후,

    기존의 SharedPreferences를 다음과 같이 변경하기만 하면 앞으로 암호화된 내용으로 저장할 수 있게 된다.

    MasterKey masterkey = new MasterKey.Builder(getApplicationContext(), MasterKey.DEFAULT_MASTER_KEY_ALIAS)
            .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
            .build();
    
    SharedPreferences sharedPreferences = EncryptedSharedPreferences
            .create(getApplicationContext(),
                    "filename",
                    masterkey,
                    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
                    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM);
    
    SharedPreferences.Editor spfEditor = sharedPreferences.edit();
    spfEditor.putString("name", "value");
    spfEditor.commit();

     

    대략적인 과정은,

    ① MasterKey 클래스로 AES256 암호화방식에 필요한 암호화 KEY를 생성

    ② masterkey를 이용하여 AES256_SIV 방식으로 name을 암호화, AES256_GCM 방식으로 value를 암호화

     

    코드를 실행하면 해당 위치에 filename.xml 파일이 생성된다.

    xml 파일을 열어보면 putString에 기재한 name과 value 값이 암호화되어 저장되어 있는 것을 확인할 수 있다.

    <map>
        <string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a9014ee82ea2f55490a152652655fb1efef8dde6bcbf6b1b64976963190f2772b186b9b7a2032654629f756a5e90c86f869078336eec8e866bd3386a99a17f5a4672e7fa93766cd6f3a435abdcc802b58165e127cc60ebdf6c7767c15573d762ce5310f2cb5bd90c681a67d8e89cf72b1b90477deebf16d0639f74b033f56d4189a88514fe1c15f45aa51d42bec2cdd16ee9281cf348103c76e7df38b0832c243526ee142614866663def61a4408c9809fe806123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b6579100118c9809fe8062001</string>
        <string name="AW0HwEn+nxee3XlmiO42S/LNoOFVaFoPlw==">AQe3bNjRFS+8RACqa2Ena+p7QkJ5gQJGQ9uMIe035LL/nZhbXItqvUP5iZBt4g==</string>
        <string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">128601969d5a385c4aa3854735e729983fdd4cffb8b0231628ac9209768b154ea28a0ad0a34f97c26b7dbcdc07a39a8bcb8f78929fd4b78aafad182fb04ab67e953be892e99536d4d777e8d4a08c476630e0393fa8c077fbeb60a8d30354c55e1886fdf35f860f0bfb55e3335f561a59f8c8099a3fee68cc04798ecabed772d1156a015a9a0ff0b9e51a4208d8d9dd3d123b0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b6579100118d8d9dd3d2001</string>
    </map>
    

     

     

    암호화된 내용을 불러와 사용하기 위해서는 복호화를 하여야 하는데,

    EncryptedSharedPreferences로 동일하게 작성한 후

    MasterKey masterkey = new MasterKey.Builder(getApplicationContext(), MasterKey.DEFAULT_MASTER_KEY_ALIAS)
            .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
            .build();
    
    SharedPreferences sharedPreferences = EncryptedSharedPreferences
            .create(getApplicationContext(),
                    "filename",
                    masterkey,
                    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
                    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM);
                    
    sharedPreferences.getString("name", "");

    으로 저장된 값을 복호화하여 불러와 평문 그대로 사용하면 된다.

     

     

    중요도가 높지 않으나,

    그래도 평문으로 저장하기 곤란한 사용자 데이터는 위와 같이

    EncryptedSharedPreferences로 암호화하여 사용하기를 추천한다.

    댓글

Designed by Tistory.