【iOS】Keychain 鑰匙串

鑰匙串升酣,實(shí)際上是一個(gè)加密后的數(shù)據(jù)庫,如下圖所示励两。
即使吧App刪除,鑰匙串里面的數(shù)據(jù)也不會(huì)丟失囊颅。

0304151a-f84e-44b1-8632-6698ec59854b.png

數(shù)據(jù)都是以 Item 的形式來存儲(chǔ)的当悔,每個(gè) Item 由一個(gè)加密后的 Data 數(shù)據(jù),還有一系列用來描述該 Item 屬性的 Attributes 組成踢代。
由于是數(shù)據(jù)庫盲憎,關(guān)鍵方法只有四種,增刪改查胳挎,對應(yīng)的是

  • SecItemAdd
  • SecItemDelete
  • SecItemUpdate
  • SecItemCopyMatching

下面簡單講述一下使用方法

SecItemAdd

    CFTypeRef result;
    NSDictionary *query = @{
        // 一個(gè)典型的新增方法的參數(shù)饼疙,包含三個(gè)部分
        // 1.kSecClass key,它用來指定新增對象的類型
        (NSString *)kSecClass: (NSString *)kSecClassGenericPassword,
        // 2.若干項(xiàng)屬性 key慕爬,例如 kSecAttrAccount窑眯,kSecAttrLabel 等屏积,用來描述新增對象的屬性
        (NSString *)kSecAttrAccount: @"uniqueID",
        // 3.kSecValueData key,用來設(shè)置新增對象保存的數(shù)據(jù)
        (NSString *)kSecValueData: [@"token" dataUsingEncoding:NSUTF8StringEncoding],
        // 可選
        // 如果需要獲取新增的 Item 對象的屬性磅甩,需要如下屬性肾请,
        (NSString *)kSecReturnData: (NSNumber *)kCFBooleanTrue,
        (NSString *)kSecReturnAttributes: (NSNumber *)kCFBooleanTrue,
    };
    OSStatus status = SecItemAdd((CFDictionaryRef)query, &result);
    if (result == errSecSuccess) {
        // 新增成功
        NSDictionary *itemInfo = (__bridge NSDictionary *)result;
        NSLog(@"info: %@", itemInfo);
    } else {
        // 其他錯(cuò)誤
    }

result類型判斷方式

kSecReturnData kSecReturnAttributes result
true true NSDictionary(包含屬性與數(shù)據(jù))
true false NSData(只有數(shù)據(jù))
false true NSDictionary(只包含屬性)
false false null

SecItemDelete

    NSDictionary *query = @{
        // 一個(gè)典型的刪除方法的參數(shù),包含兩個(gè)部分
        // 1更胖、kSecClass key,它用來指定刪除對象的類型隔显,必填却妨。
        (NSString *)kSecClass: (NSString *)kSecClassGenericPassword,
        // 2、若干項(xiàng)屬性 key括眠,可選彪标。
        // 例如 kSecAttrAccount,kSecAttrLabel 等掷豺,用來設(shè)置刪除對象的范圍
        // 默認(rèn)情況下捞烟,符合條件的全部 Item 都會(huì)被刪除
        (NSString *)kSecAttrAccount: @"uniqueID",
    };
    OSStatus status = SecItemDelete((CFDictionaryRef)query);
    if (result == errSecSuccess) {
        // 刪除成功
    } else {
        // 其他錯(cuò)誤
    }

SecItemUpdate

    // 1、找出需要更新屬性的 Item
    // 參數(shù)格式與 SecItemCopyMatching 方法中的參數(shù)格式相同
    NSDictionary *query = @{
        (NSString *)kSecClass: (NSString *)kSecClassGenericPassword,
        (NSString *)kSecAttrAccount: @"uniqueID",
    };
    
    // 2当船、需要更新的屬性
    // 若干項(xiàng)屬性 key
    NSDictionary *update = @{
        (NSString *)kSecAttrAccount: @"another uniqueID",
        (NSString *)kSecValueData: @"another value",
    };

    OSStatus status = SecItemUpdate((CFDictionaryRef)query, (CFDictionaryRef)update);

    if (result == errSecSuccess) {
        // 更新成功
    } else {
        // 其他錯(cuò)誤
    }

SecItemDelete

    NSDictionary *query = @{
        // 一個(gè)典型的刪除方法的參數(shù)题画,包含兩個(gè)部分
        // 1、kSecClass key德频,它用來指定刪除對象的類型苍息,必填。
        (NSString *)kSecClass: (NSString *)kSecClassGenericPassword,
        // 2壹置、若干項(xiàng)屬性 key竞思,可選。
        // 例如 kSecAttrAccount钞护,kSecAttrLabel 等盖喷,用來設(shè)置刪除對象的范圍
        // 默認(rèn)情況下,符合條件的全部 Item 都會(huì)被刪除
        (NSString *)kSecAttrAccount: @"uniqueID",
    };
    OSStatus status = SecItemDelete((CFDictionaryRef)query);
    if (result == errSecSuccess) {
        // 刪除成功
    } else {
        // 其他錯(cuò)誤
    }

SecItemCopyMatching

    CFTypeRef result;
    NSDictionary *query = @{
        // 一個(gè)典型的搜索方法的參數(shù)难咕,包含三個(gè)部分
        // 1课梳、kSecClass key(必填),它用來指定搜索對象的類型
        (NSString *)kSecClass: (NSString *)kSecClassGenericPassword,
        // 2余佃、若干項(xiàng)屬性 key(可選)惦界,例如 kSecAttrAccount,kSecAttrLabel 等咙冗,用來描述搜索對象的屬性
        (NSString *)kSecAttrAccount: @"uniqueID",
        // 3沾歪、搜索屬性(可選)
        // 例如 kSecMatchLimit(搜索一個(gè)還是多個(gè),影響返回結(jié)果類型)
        // kSecMatchCaseInsensitive 是否大小寫敏感等
        (NSString *)kSecMatchLimit: (NSString *)kSecMatchLimitAll,
        (NSString *) kSecMatchCaseInsensitive: (NSNumber *) kCFBooleanTrue,
        // (可選)如果需要獲取新增的 Item 對象的屬性雾消,需要如下屬性灾搏,
        (NSString *)kSecReturnData: (NSNumber *)kCFBooleanTrue,
        (NSString *)kSecReturnAttributes: (NSNumber *)kCFBooleanTrue,
    };
    OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, &result);
    if (result == errSecSuccess) {
        // 新增成功
        NSDictionary *itemInfo = (__bridge NSDictionary *)result;
        NSLog(@"info: %@", itemInfo);
    } else {
        // 其他錯(cuò)誤
    }

result類型判斷方式

kSecReturnData kSecReturnAttributes kSecMatchLimit result
true true kSecMatchLimitAll NSDictionary(包含屬性與數(shù)據(jù))數(shù)組
true true kSecMatchLimitOne NSDictionary(包含屬性與數(shù)據(jù))對象
true false kSecMatchLimitAll NSData(只有數(shù)據(jù))數(shù)組
true false kSecMatchLimitOne NSData(只有數(shù)據(jù))對象
false true kSecMatchLimitAll NSDictionary(只包含屬性)數(shù)組
false true kSecMatchLimitOne NSDictionary(只包含屬性)對象
false false kSecMatchLimitAll 空數(shù)組
false false kSecMatchLimitOne null

參考文檔
https://developer.apple.com/documentation/security/keychain_services/keychain_items?language=occ
Demo 地址
https://github.com/huangrrui/Key-chain

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挫望,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子狂窑,更是在濱河造成了極大的恐慌媳板,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泉哈,死亡現(xiàn)場離奇詭異蛉幸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)丛晦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門奕纫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人烫沙,你說我怎么就攤上這事匹层。” “怎么了锌蓄?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵升筏,是天一觀的道長。 經(jīng)常有香客問我瘸爽,道長您访,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任剪决,我火速辦了婚禮洋只,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘昼捍。我一直安慰自己识虚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布妒茬。 她就那樣靜靜地躺著担锤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪乍钻。 梳的紋絲不亂的頭發(fā)上肛循,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音银择,去河邊找鬼多糠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛浩考,可吹牛的內(nèi)容都是我干的夹孔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼搭伤!你這毒婦竟也來了只怎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對情侶失蹤怜俐,失蹤者是張志新(化名)和其女友劉穎身堡,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拍鲤,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贴谎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了季稳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片擅这。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绞幌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情一忱,我是刑警寧澤莲蜘,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站帘营,受9級(jí)特大地震影響票渠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芬迄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一问顷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧禀梳,春花似錦杜窄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嘴瓤,卻和暖如春扫外,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背廓脆。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工筛谚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人停忿。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓驾讲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子蝎毡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353