(譯)使用AndroidX安全庫(kù)加密SharedPreferences

本文譯自Encrypting Shared Preferences with the AndroidX Security Library算墨,介紹了AndroidX安全庫(kù)中EncryptedSharedPreferences的使用汁雷。備注:僅支持minSdkVersion 23及以上侠讯。

本文首發(fā):http://yuweiguocn.github.io/

《離思五首·其四》
曾經(jīng)滄海難為水,除卻巫山不是云熬苍。
取次花叢懶回顧袁翁,半緣修道半緣君。
-唐代柄驻,元稹

Android框架給我們提供了SharedPreferences焙压,它是一個(gè)用于存儲(chǔ)小量鍵值數(shù)據(jù)很好的工具。當(dāng)存儲(chǔ)一些敏感數(shù)據(jù)野哭,重要的是SharedPreferences存儲(chǔ)的數(shù)據(jù)是明文的幻件。我們應(yīng)該加密敏感的數(shù)據(jù)不要讓它被窺視绰沥。我們可以怎樣做?

一種方法是我們使用Android密鑰庫(kù)自己寫加密包裝SharedPreferences零截。不幸的是這會(huì)相當(dāng)復(fù)雜并且涉及大量配置秃臣。另一種方法是使用第三方庫(kù),這意味著我們需要花時(shí)間找到一個(gè)合適的绍撞。值得慶幸的是AndroidX安全庫(kù)最近被添加,這讓min-sdk為23+的應(yīng)用存儲(chǔ)加密SharedPreferences變得容易和方便章贞。

詳細(xì)使用

首先在module的build.gradle文件中添加依賴非洲。

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

這是在寫本文時(shí)的最新版本。查看library’s releases page獲取最新版本败京。

需要注意的是這個(gè)庫(kù)當(dāng)前是alpha階段梦染。這意味著雖然功能是穩(wěn)定的,部分API在后續(xù)版本可能被修改或移除泛粹。

添加了依賴之后肮疗,下一步是在Android KeyStore創(chuàng)建一個(gè)加密master key和store伪货。安全庫(kù)提供了一個(gè)容易的方法處理這個(gè)。將下面的代碼添加到你計(jì)劃創(chuàng)建EncryptedSharedPreferences實(shí)例前面蒙挑。

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

我們指定了一個(gè)默認(rèn)的key巍举,AES256_GCM_SPEC,用于創(chuàng)建master key。雖然推薦使用這個(gè)規(guī)范炭分,如果你需要對(duì)如何生成密鑰有更多的控制你也可以自定義KeyGenParameterSpec剑肯。

最后我們只需要一個(gè)EncryptedSharedPreferences實(shí)例,它對(duì)SharedPreferences進(jìn)行了包裝并且為我們處理所有的加密呀忧。不同于SharedPreferences,我們可以從Context#getSharedPreferences或Activity#getPreferences獲取胰坟,我們需要?jiǎng)?chuàng)建自己的EncryptedSharedPreferences實(shí)例泞辐。

val sharedPreferences = EncryptedSharedPreferences.create(
    "shared_preferences_filename",
    masterKeyAlias,
    context,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

我們指定了shared preferences的文件名咐吼,之前創(chuàng)建的masterKeyAlias,和一個(gè)context厢塘。最后兩個(gè)參數(shù)是key和value加密的scheme肌幽。它們是庫(kù)提供的唯一的選項(xiàng)牍颈。

創(chuàng)建了EncryptedSharedPreferences實(shí)例后煮岁,可以使用它像SharedPreferences一樣讀取和存儲(chǔ)值∫鄙。總而言之步氏,就像下面的代碼一樣:

val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)
val sharedPreferences = EncryptedSharedPreferences.create(
    "shared_preferences_filename",
    masterKeyAlias,
    context,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
// storing a value
sharedPreferences
    .edit()
    .putString("some_key", "some_data")
    .apply()
// reading a value
sharedPreferences.getString("some_key", "some_default_value") // -> "some_data"

再次檢查結(jié)果

我們?cè)鯓又罃?shù)據(jù)被加密了荚醒?讓我們看下shared preferences文件中的內(nèi)容。如果你想shared preferences文件中的內(nèi)容侯繁,可以從StackOverflow找到答案泡躯。使用正常的SharedPreferences丽焊,文件內(nèi)容如下:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="some_key">some_data</string>
</map>

正如我們看到的咕别,key和value沒有被加密惰拱。使用EncryptedSharedPreferences,文件內(nèi)容就像這樣:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="ATP1ABa3NIlOap2c7iNkVaUcQmTocrnpkXl0PyI=">AU+p3hwqCgvlDOtIaawFHWVDf4rFsqghM7ivFTEJesrRp19D+zk7tqsqlGZPLAbryHI=</string>
    <string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a901802f1a5d2fbc5cd3c9b545a89ca8ace8f125f8e601a8ac51929303ead8a2bbdf5428bd054360b97c1727ef93ef63b64f43ceac92156f3aee9402dd247009d9779571c6ceacfcd4e7123665cc9dd94c44c5c2c6241a8de070d365d94010f8affb6097d4b0fec1c628120a8f901c23caa03d32ecc6ce270e3cc3341e6455b87a80474b3818c3ad678faa4199a9a45078b218c89b8c5a8cbd1780a68b4f8196eb5153b6422df2bdfee6541a44089680d49f03123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b65791001189680d49f032001</string>
    <string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">128801da6fdef289b2c6e2933c341b1b3df3b39330671d76df362ba8b0a1d807cdc9d2d4d7bc3062139377e4fa61428f3817c0e368c3196c95fdbcca3c37075e7132abae1fe0f128ceef7278a06a01e0cacf29edc1f3c1c1d37875c27c0cf5d86d0b2bb39efcac84828f664838b77aa4c406028af912e860cad8bff51aca6aaf45167d5ab5c8e57bf05db61a44089cbca7fd04123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b65791001189cbca7fd042001</string>
</map>

可以看到key和value被加密了并且存儲(chǔ)了兩個(gè)keysets,一個(gè)是shared preference的keys另一個(gè)是values翔冀。Keysets包含加密和解密shared preference數(shù)據(jù)的key纤子。之前創(chuàng)建的master key用于加密這些keysets,這樣它們就可以和提供的數(shù)據(jù)一起存儲(chǔ)在shared preference文件中泽论。

結(jié)語

Android的SharedPreferences對(duì)于存儲(chǔ)key-value數(shù)據(jù)是一個(gè)很有用的工具卡乾,對(duì)于敏感數(shù)據(jù),這是一個(gè)很好的加密它的方法鹦赎。最近的AndroidX安全庫(kù)是一個(gè)受歡迎的新功能误堡,它為我們提供了一個(gè)簡(jiǎn)單易用的加密方案锁施。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市肩狂,隨后出現(xiàn)的幾起案子基跑,更是在濱河造成了極大的恐慌,老刑警劉巖栅螟,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件力图,死亡現(xiàn)場(chǎng)離奇詭異掺逼,居然都是意外死亡吕喘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門募舟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闻察,“玉大人,你說我怎么就攤上這事辕漂∧卦睿” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵钉嘹,是天一觀的道長(zhǎng)鸯乃。 經(jīng)常有香客問我,道長(zhǎng)跋涣,這世上最難降的妖魔是什么缨睡? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮仆潮,結(jié)果婚禮上宏蛉,老公的妹妹穿的比我還像新娘。我一直安慰自己性置,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布鹏浅。 她就那樣靜靜地躺著嗅义,像睡著了一般。 火紅的嫁衣襯著肌膚如雪隐砸。 梳的紋絲不亂的頭發(fā)上之碗,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音季希,去河邊找鬼褪那。 笑死幽纷,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的博敬。 我是一名探鬼主播友浸,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼偏窝!你這毒婦竟也來了收恢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤祭往,失蹤者是張志新(化名)和其女友劉穎伦意,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體硼补,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驮肉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了括勺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缆八。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖疾捍,靈堂內(nèi)的尸體忽然破棺而出奈辰,到底是詐尸還是另有隱情,我是刑警寧澤乱豆,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布奖恰,位于F島的核電站,受9級(jí)特大地震影響宛裕,放射性物質(zhì)發(fā)生泄漏瑟啃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一揩尸、第九天 我趴在偏房一處隱蔽的房頂上張望蛹屿。 院中可真熱鬧,春花似錦岩榆、人聲如沸错负。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)犹撒。三九已至,卻和暖如春粒褒,著一層夾襖步出監(jiān)牢的瞬間识颊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工奕坟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留祥款,地道東北人清笨。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像镰踏,于是被迫代替她去往敵國(guó)和親函筋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子沙合,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容