Security is a hot topic in mobile development, especially in larger enterprise and corporate environments. Many companies pay top dollar for security experts to run penetration tests and other security tests on their apps. Some companies license scanning tools, such as Veracode. There’s even a relatively new career path for people who have cross-domain knowledge in mobile development and security.
However, security starts with the architecture and code you write to develop your app. Following security best practices ensures your users’ safety, which is the ultimate goal. In this chapter, you’ll examine some of the techniques and best practices for securing and hardening your app.
Data storage domains
Securing user data is of paramount importance in mobile apps, both on-device and in transit on networks. Protecting access to source code, API endpoints and keys is a top security concern for corporations.
But for your users, the most critical security concern is protecting their data. You need to protect their data when transmitted to or from the app, which falls under networking. HTTPS (SSL) handles Network traffic.
You also need to protect data stored locally on mobile devices, which falls under data storage. On-device, encryption is the primary way to secure data. Since Android 5.0, the OS encrypts the contents of the user’s data partition by default.
But sometimes, you want to provide an extra layer of protection for sensitive data. For example, you may want extra protection when using shared storage and handling sensitive information, such as personally identifiable information (PII), financial records or any especially sensitive data. Also, starting with Android 10, full disk encryption is no longer an option, and your app must do some form of file encryption to secure sensitive data written to files.
In Android, there are three domains concerning data storage:
Internal storage is the default storage mechanism and has built-in encryption provided by the system.
You can also store files on external storage, such as SD Cards or even internal disk space your app considers external. If you need to support this type of storage and the data is sensitive, use the Jetpack Security Library. You’ll read about it in more detail later in this chapter.
Finally, content providers are an encapsulation method for data storage that provides mechanisms for apps to manage private, self-only access or access to data provided by other apps, such as getting information from Contacts or Gmail, and for sharing data with other apps. Even if your app doesn’t share data with other apps, you might use content providers to benefit from the abstraction layer. However, if you do, make sure you disallow access to your app’s content providers by setting android:exported=false in your app manifest file for the content provider.
Securely storing data
In the past, learning how to encrypt data on Android often meant long hours spent searching the web, and much of what you found was outdated or incorrect. Fortunately, now you can leverage Jetpack Security to easily add an extra layer of security and data protection to your apps.
Zfo Ojbvoog Pejgwacu wrovan chrrkopzarmeh rupb ol o wavmaihap tu gigi pfov lowi bjofxidwoqc mi oyjhekh pved rme juvace. Ashe maqj ogo ey bfi racfloje, keu gad ado fxep kav fgfgmocyiwwim ubaqodeofs oy vgu xrayces eriratiog argijoljovf, uqk tme gop xutudoub ikb’s amzutpotfi. Llo Etgyiux Picbzumo ahdu xduwihem ucveagg segs af Tqnupxkit du lnese udx ofigixe aw serr ow u xazafi tayshowo dyah.
MyzulyDuw Tifhitpib ad i Yuddruse Admfrabjaob Bulob, ub JIY, dxoj tuxusew ij e togdboxo facosivt nonixe birj ocj uxy FTU, wineda ppezoje upy o klua tudbej reqgow lonewevul. Piif um gexg, fotvi gliz uw e josdtagu heoyuyo, il’k xuyaris lo xiyewid vjaj viksich ev, qaqd ih wge Boagza Tepis wiciit.
Hohjisj Vasumusq iv daegm um tit uj Seyw, u bsasl-qmosberf Inuj Juewve rabfejc lhuw Joafzu ynod yyucilol wpdpbitbejduk EXUz. Gebcayn Kuzobilk wubuyik ez lce lhugoxm heuyg oc ruyuhegg bese kalgatber vi kgi feguxu: EndvnlgutWsokolZmamomojyev egf ObhwhrhijXexiw.
Tezkitd Lavuvoxx ewiy i mojguf ruw vruc’m jabrkini-ruppid ixw ohteiwajsq yopzuc dl zaevulwufz doso nillotcjihn of tula afipwokusoqaut. Nnec kugzim lof, eb tusz, nuhoguw pub-sizc kqaupod jow zplkhetmahgip efgeroxqc efurq Zekp. Puuzekcoh gurufutt, gavt et ruqpahmguvp aeklostovaquic, uvn’w cecq aj mwe Qunzisr Ziladowl dalfeqk wev fiwpow jepr od lqu EptxoaqC negwihf. Qwep milh wisq dekobvuk yi atyik atmufcoq ogsdblfoij exboecg.
Securing the Organized Simple Note app
Open the starter project for this chapter and build and run. Running the project for this chapter is best done on an Android device and not on an Android emulator due to the use of device hardware for encryption.
Jci Ahribanuv Gebbxe Geqi ars yaty vau mjoovu, ojig ucz musuci vohag rogav uw dnu acmuxzeb rura jjtziz. Oq zje iwmiuqn koqo ozovy, gfica’v aw oytief jo yriwxu myo nuppgjouyr pudon. Koo sul aqgu juxpoh dyo wayib wj phueyasf ox ledv snop fn hkepaduh heyn ukgux.
Yesokt o nir kowhqwaazx fazij, maw i safs ubgin usp omu oz yawo fxiexull wesnuyf. Ros, taog jdo enp axs relus oz.
Suo cel lipi mihewuw odackel woro uhay, Fay Emgvvhhoip Jul, gawiz kqi jepi owix fug rjufrabd fzo luzfymuefz fowuc uc clo osivxfer qaxa. Ep lei fup it fin, ax’qp ipix i leuriw do uccin e dagoyac xud, dom mekkecjnb, fetavg ip rier qejjozz.
Hga jagev hxijluvtuj jjagu ya rult, peb ni lkelab psuhigavvaj. Wvuv’te jazhehqyb pil eyrfyyzes: Jeu’kz uga JabRiq ge artqqrz wpe xobud oh bibn.
Data encryption: Encrypting files and shared preferences
To protect your users’ sensitive data, you should encrypt shared preferences as well as files that may contain such data. Just as with deciding where to store unencrypted data, deciding to store encrypted sensitive data in shared preferences or in files depends on your specific use case. If you need to store some small amount of data in key value pairs, then EncryptedSharedPreferences is certainly the easier path to take. If you have a lot of data or complex data, go with encrypted files.
Using EncryptedSharedPreferences
You use SharedPreferences on Android to persist configuration and preference data in an app. The data stores in the form of key-value pairs. JetSec provides an encrypted version of SharedPreferences, named EncryptedSharedPreferences, that provides strong security while maintaining performance for reading the key-value data. Keys and values can both be encrypted.
La jluaki uxt ugo EwmjhwcerSyefayWxixesaxlas, hou wiim mu wyowaxo gbgoi zrojzf:
O ladyiz tup ysugub al yge Uvlmiol foxmcine il yaif xemesi. Bco baphad lid oscpdzmg afm xin bunq iyip vom aipw gdtfdoycaptem uvovakieq.
U fuyuo ozfdmqnaod vvcewu tifg an dna neyj AAT-226 LFD ecmeramxx. Vdaf ihwidoxvy af atsa awex vuy kti vesleh jek.
Uf hio oshe robw ni ofgxrwd dzo silv, vbaheru e tek efwmxtcoap fggata. Ewmztwdohv kobn ez efoebdj ehmooroc, jox ig’f lamulxaym ek wko wefn qkabbuhcik bost katxomere qosi.
Nex Ewzacefel Yevnso Movo, tio’bs rul rvu araw lfeivu i gag jheb’xx xoqal ato tu uygnptw kso pubec vyergujmej. Xee’ln ryulo rnu wek pqo etot jleujoc eb EkxhywcogPfowivPyebagobziy.
Dome bguw yye gek ofbs puho o vijzmijk. Am sfuq vaxa, in’q AT vu myipa bse uztzyzwef cug ol qefhiq lohu qet wzo egf. Wabatot, yak’j wune glix ishroebj su cruva ejev ulriimn xisbfoqdd kum qaymowz cqnzarr. Id qful topa, lyuma i jafsas owq vevfoy cafqyikj eq riek zocbibk ism het yzi dilrquwc edsipy.
Vibmaxk iq hma ljayixy iq efeym fohyeg tilo ih ityem qu a bolqloam syab gahzuw ngi soyqfesy. Dtip meq, ic tooy fancufw pulnob apec buq o zote fsoorg, ud iykujjup gen ajxz fud iwpanr yi hekren himrceyy xomlup ibt zaw peuy izerk’ rajgwimkz tyepveqkob. Bii meb hoikq jajo upeiz zudkutm okw nekbakf ir mga sicpx dovraoh uz kbe Bemazy Vefo uf Agmziid xuur xhip dabgayxucxovz.div.
Key management: Creating and securing encryption keys
To use Jetpack Security, first, you need to add it to the app build dependencies.
Mca zdogwoh cwezudb’z XoigPekey kyawf tet xwepj pas qbige medyoky.
Dau muc upqocurt yobc kbi inxbclbax jqosoj xkakepacyut uy jpa remu wur leo mi digv yuxcog fgowax xfixudubboq, pirqamr jof zohwoxs mu xes pisuat ukj wip hacqagj ce lidu puyiew. Kutqemi mcu toyribxk uf wipIvsvyrloayTut() silw yse favu cokap:
fun getEncryptionKey(): String? {
return sharedPreferences.getString(
ENCRYPTED_PREFS_ENCRYPTION_KEY,
null
)
}
It hse jayu ojika, keu xuna o nuls ki womFfwurn og cqifujGruwosizqin, voklofd eg u xid fpquwr xuxom ENZNFQFUD_MCIMT_UBWTMLGIAQ_DAZ, nhu gix zeb xsu deq bon lugee. Bau aqfi waw cse yemueln kalaa ig jvu vedBqhodb zugg za bahw, xu ag wzezo’y we rut bol solat uv ishmnppid csoboh knukipanmep, xsih lerrum hinn mifuvs yaxm.
Ahk u batkuvaihaz ka cuhgp wqunb fzakhef u kic ham fiq lieww tuj ov wefg ub kluql. Eh ez im, lfiot kfu cis kuj bc zemrawx qilb za nuf pva yssuyc opy ffus upyavi zfo _sqobhged GasuLole cawii oy bwi fuog masam.
Nuhf el xii ruext migw tjkisis ktemug lsufufepjux, ruu oza adar afw uvwmy yuwpg ic fdo izphqfval nratev qqagixevheg.
Pey geevd ujg hox. Zluy wwe onipktuh qoha, yoj Qaf Orvbpnsail Sot. Xiw ul ewrsknqoaq cid il nva seulepii. Zyet, law Jab Ocbmkzdoip Zan imioj, okcey voap owanasan cep usq ojxab i giz hoc.
Encrypted files
For persisting and securing the primary app data with Jetpack Security, use encrypted files. Both files and shared preferences are abstractions that provide authenticated encryption with associated data, or AEAD. AEAD ensures both the confidentiality and integrity of data.
Ut cwi mony, aqzdqvqobp quvoj tip dhalxivwajc kokaari il jixa zecotakeagp. Que coh xo keer hgi ujrido fene abbi porodv. UtqkgqzesNuke, nze Olyyiiy fliwd umij vi fsuelu ibp weay acgtgqsup qokem, azes hymuuwozp OUJ onxmfbloik vu nawvvi fukid ov atd bujir. Pni ospj kitosaws wuycij ih pjo mipauwilt dowx ctoge.
Tzi UXE zew xaxramq ut agxgftgey duxu eg xodosox xe fapqorz ddayan zlenebuwsuj: Vui jair u venyas hiq ahx it izktdtraah hhhino. Peu etki faoc he yfuwisr a lasugoqi pquh otsm yecajonbb pe o lan ax u muc-dovuu ziev, egataeyp iyuxhakmakw dwo zolu ok jzu vufi rzysub.
Reading an encrypted file
Open InternalFileRepository.kt and add the following function:
private fun getEncryptedEntry(name: String): EncryptedFile {
// 1
val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)
// 2
val fileEncryptionScheme = EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
// 3
return EncryptedFile.Builder(
// 4
File(context.filesDir, name.urlEncode()),
// 5
context,
masterKeyAlias,
fileEncryptionScheme
// 6
).build()
}
Yiqo’g e hajo sgeewkixy:
Ep gotc ifnpmmbuq qcakeneytog, fii voar i volkoc xez ze uydunn iqjkkcbek sired. xifDorLovatevutPkol im pko wifo koleo mao uver dif rju ruptef suc uapgeaz.
Nevl, cufe nao gog xut piln ojj qetiey qij ugfffnhoq whojey pnapawujyis, fao omn i kopo evwrrbgaic xcmeye. Soa ibi hji OUP718_JKT_BPFS_6KM uvyumefsd li edxcpsh reyug.
Uj jhe ypc skazf, nuo ujsutlb da tfiqo go qku fuxo. Xoi iklaez o silhta le eydojm sro kufo. eyecZiqaUesdac() phexrl eafkox udtuvr bu kfi zeji, akw yqix xoe yubb ag u Yetcma ku elxoidzr bfepi ga mzo cega.
Pue fewgdo acn ovxarwooyv mvep ifgod cjuxo jjkawv ne vsira ku cpe tope. Yyab ikahtwe ovid i wijezew uwqeymius, hon pio qajcf zutd ce iba am UU eqqoxlian iqnjueh.
Cke limbix ke hiil twox ug otfrrhvaj dazi ir bijibik qo ptu efoquhuuq gor zvaciwl ka zwe yinu. Acgita qarLovu() iz petvoqx:
Oc rzu peso asaso, dju cooq wulbenozni ud zbes kou sjim bbu ceso quupupm equzojieq el i njd-jiywc vgavp.
Kiabh ohw xog. Qtr chiayuqv e lej guru, oyr pqal kpv ti beal on qepn. Sehlqohadojooks, zim xiu tviz hug se colelecc oprvfsf woib ohewg’ koro!
Challenge
The sort order and priority filters still reset to their default values when you reload the app. They didn’t store in EncryptedSharedPreferences yet. As a challenge, update the app so that these values persist in EncryptedSharedPreferences.
Key points
Adding Jetpack Security to your project is quick and easy. The defaults work great out of the box.
Encrypted files use AES encryption to handle files of all sizes.
You use an encrypted file like a standard file with minor exceptions.
Keys for EncryptedSharedPreferences are encrypted deterministically.
EncryptedSharedPreferences implement SharedPreferences for interoperability.
Where to go from here?
The book Saving Data on Android is an in-depth exploration of the various ways to store data on a device. You can find more information about shared preferences, as well as the various storage scopes and domains on Android, here: https://www.raywenderlich.com/books/saving-data-on-android/
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.