Android(Kotlin)

Room SQLCipher

----___<<<<< 2022. 12. 21. 19:47

그 어떤곳에서도 한국어로 Room 데이터 암호화 및 SQLCipher에 대한 설명글이 없어서 제가 번역해서 정리하기로 했습니다.

(유독 안드로이드 관련 정보는 한국어를 찾기가 어렵네요)

 

이 글에 대한 번역이고 코드는 여기에 있는 코드를 참고했습니다.

 

구글에서 일하는 형님이시니 믿고 번역해보겠습니다.

 

 

Protect your Room database with SQLCipher on Android

Android에서 SQLCipher로 Room 데이터베이스 보호

 

Welcome to this serie of articles about Android Security and how you can improve tremendously the protection of your users’ privacy, by implementing 3 things that provide a great effort/safety ratio.

3가지 보호 방법을 소개해줄게

 

Today we are going to look at protecting the Room Database. In deep Room database is handle by SQLite and the file is saved without encryption, which can expose your users’ data, for instance on a rooted device.

ROOM은 암호화 없이 저장되서 루팅된 장치에서 데이터가 보여

 

 

Add Room and SQLCipher into your gradle build file.

적당히 implement 해주고

 

implementation 'net.zetetic:android-database-sqlcipher:$sqlcipher_version@aar'

 

 

How SQLCipher works

어떻게 SQLCipher는 동작하냐


SQLCipher add an encryption layer to SQLite. The encryption is pretty strong, using AES-256, a standard in the industry.

The developer will have to provide a Master Key that will be used to encrypt the data. It is the developer responsibility to protect and secure the Master Key. (could use for instance userID + salt + hash)

SQLCipher encrypt/decrypt page by page, which improve the performances, also each page is encrypted differently.

This is only an overview of the key feature. If you want an exhaustive understanding, please check SQLCipher Design

SQLCipher가 AWS-256를 이용해서 보호하고 개발자는 마스터키값을 제공해야함. 어쩌고 저쩌고

 

Compatibility with Room

 

Because SQLCipher is an extension of SQLite, it is compatible with all SQLite functions, it doesn’t disturb Room functionings.

You can continue using your DAO as usual, nothing special is required.

 

ROOM과 호환 잘된다.

 

Implementation


As you can see in the following piece of code, only a few lines of code are required, which make it a quick-win to implement.

 

val builder = Room.databaseBuilder(
context.applicationContext,
Database::class.java, "encrypted.db")
val factory = SupportFactory(SQLiteDatabase.getBytes("PassPhrase".toCharArray()))
builder.openHelperFactory(factory)

builder.build()

 

Yes, you read it right, only the 2 lines in bold are required to make your DB encrypted.

But let’s get back to them for a moment. We first need to create the (SQLCipher) SupportFactory , and we will provide the passphrase we want to use as a MasterKey for the encryption.

Then we tell our Room database builder, to use this factory, thanks to openHelperFactory() .

 

저거 2줄만 추가해주면 알아서 돌아갑니다.

 

From now on, the Room Database is encrypted.

⚠️ Make sure your passphrase is NOT hardcoded and is secured, like using the Android KeyStore

 

암호 하드코딩 하지말고.

 

뭐 여기까지 하면 저희의 목적까지 안 것 같은데 조금 더 읽어보겠습니다.

 

Performances
This is probably the most interesting part. Our users are expecting lightning fast apps, this is also why, us developers like native development. So let’s be clear, they will be drawbacks when applying a security layer of encryption.

Before we continue, SQLCipher is offering full encryption DB + Memory protection, but it is possible to disable the memory protection, which can improve performances. The memory protection consists in locking memory segments and wiping the memory after use.

퍼포먼스는 Memory protection을 해지해서 올릴 수 있다 아래와 같이

 

 

여기에서 궁금한게 ON/OFF 기본값은 뭔가 하면 여기를 보시면

 

https://discuss.zetetic.net/t/what-is-the-purpose-of-pragma-cipher-memory-security/3953

 

What is the purpose of PRAGMA cipher_memory_security?

What is the right place to execute PRAGMA cipher_memory_security = OFF;? Can I do it in onUpgrade method? So it will be executed only one time. Or I need to execute it each time I open a database. Can you tell what exactly this pragma does and what is the

discuss.zetetic.net

 

PRAGMA cipher_memory_security is enabled by default. 라고 나옵니다.

 

Migration

In order to migrate a non-encrypted/plain SQLite Database to SQLCipher, the team provide a function sqlcipher_export that can be used in a SQL Query ran in the Room migration script as a RawQuery.

 

RawQuery로 처리할 수 있습니다.

 

sqlcipher_export 를 이용해서 아래와 같이 쿼리날리면 됩니다.

 

database = SQLiteDatabase.openOrCreateDatabase("clearDatabase.db","", null);
database.rawExecSQL("ATTACH DATABASE '${encryptedDbPath}' AS encrypted KEY '${passphrase}'");
database.rawExecSQL("select sqlcipher_export('encrypted')");
database.rawExecSQL("DETACH DATABASE encrypted");
database.close();

 

 

Conclusion


This article conclude my series of articles about Android Security. We have seen EncryptedSharedPreferences, SSLPinning and SQLCipher. I believe implementing these 3 things is feasible for most developers as it requires reasonable amount of work, for great security benefits.

Regarding SQLCipher, I highly recommend it, don’t be afraid about the performances. I have a fair experience with it and I never really had any noticeable slowness. Of course it will depends of your dataset and your queries, but indices can help a lot.

 

결론은 뭐 쓰면 좋다 라고 하는겁니다. 끝.

 

 

 

 

- 참조

 

https://sonique6784.medium.com/protect-your-room-database-with-sqlcipher-on-android-78e0681be687

 

Protect your Room database with SQLCipher on Android

Improve tremendously the protection of your users’ data, by implementing encrypted database with SQLCipher for Room

sonique6784.medium.com

https://github.com/sonique6784/SQLCipherPerformance

 

GitHub - sonique6784/SQLCipherPerformance: SQLCipher Performance benchmark

SQLCipher Performance benchmark. Contribute to sonique6784/SQLCipherPerformance development by creating an account on GitHub.

github.com

 

'Android(Kotlin)' 카테고리의 다른 글

Unix Time to SimpleDataFormat  (0) 2023.01.09
Paging Advanced  (0) 2022.12.26
StateFlow / SharedFlow  (0) 2022.12.15
Hot Stream / Cold Stream  (0) 2022.12.15
LiveData emit / emitSource  (0) 2022.12.13