日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

SSKeychain

發(fā)布時(shí)間:2023/11/30 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SSKeychain 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Keychain 使用? ---為了實(shí)用最大化我覺(jué)得我應(yīng)該直接先說(shuō)使用!

當(dāng)然是使用第三方庫(kù)啦:sskeychain 3000+星星的庫(kù)不開(kāi)玩笑。github地址:https://github.com/soffes/sskeychain

導(dǎo)入完之后首先,編譯一下有無(wú)錯(cuò)。

如果是自己手動(dòng)導(dǎo)入:

1.把SSKeychain.h SSKeychain.m SSKeychainQuery.h SSKeychainQuery.m 復(fù)制到工程

2.添加Security.framework 怎么添加?點(diǎn)一下那個(gè)+?

?

3.SSKeychain.h有錯(cuò)?把SSKeychain.h 中的#import <SSKeychain/SSKeychainQuery.h> 換成?#import <Foundation/Foundation.h>?#import "SSKeychainQuery.h" 吧。

還有錯(cuò)?作為小白我的也不知道了,發(fā)我郵件一起討論吧。

?

?

接下來(lái)演示4個(gè)過(guò)程

基本說(shuō)明:儲(chǔ)存的數(shù)據(jù)有三個(gè) 1.服務(wù)名(這個(gè)方便對(duì)賬號(hào)密碼進(jìn)行分類)2.賬號(hào)3.密碼 而這三個(gè)數(shù)據(jù)都是NSString (如果要存其他類型呢,請(qǐng)看后面吧)

所用到的API :

添加和更新都用這個(gè): + (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account ;

查詢密碼:+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account;

刪除:+ (BOOL)deletePasswordForService:(NSString?*)serviceName account:(NSString?*)account;

1.添加一條鑰匙 ? ?(這個(gè)鑰匙的信息 由 服務(wù)名+賬號(hào)+密碼 組成)

記得添加頭文件

#import "SSKeychain.h"

#import "SSKeychainQuery.h"

?

//先定義一下要用的東東

? ??NSString *serviceName= @"com.keychaintest.data";

? ? NSString *account = @"m4abcd";

? ? NSString *password = @"12345678";

//加入鑰匙串!

? ? if ([SSKeychain setPassword:password forService:serviceName account:account]) {

? ? ? ? NSLog(@"success !");

? ? }

說(shuō)明:就是這么簡(jiǎn)單咯。

2.查詢

1.查詢某service 下 count 的密碼并且打印出來(lái):

  NSLog(@"%@",[SSKeychain passwordForService:serviceName account:account]);

2.查詢service下所有鑰匙:

? ? ?NSArray *keys = [SSKeychain accountsForService:serviceName];

這是我的輸出:

2016-03-04 15:08:43.785 keychaintest[31342:4403403] (

? ? ? ? {

? ? ? ? acct = m4abcd;

? ? ? ? agrp = test;

? ? ? ? cdat = "2016-03-03 07:10:58 +0000";

? ? ? ? mdat = "2016-03-04 07:08:43 +0000";

? ? ? ? pdmn = ak;

? ? ? ? svce = "com.keychaintest.data";

? ? ? ? sync = 0;

? ? ? ? tomb = 0;

? ? }

)

說(shuō)明:返回的結(jié)果為數(shù)組,數(shù)組成員就是我們查詢的鑰匙,這里只有一個(gè)鑰匙,而鑰匙信息以字典的形式構(gòu)建的,鍵acct 就是count,鍵svce 就是serviceName。密碼在哪里?用方法1去取吧騷年!

3.查詢本appkeychain的所有鑰匙

  NSArray?*keys =?[SSKeychain allAccounts];?

3.更新

? ? if([SSKeychain setPassword:@"321321" forService:serviceName account:account]){

    NSLog(@"set success!");

  }

4.刪除 

? if([SSKeychain?deletePasswordForService:serviceName account:account]){

    NSLog(@"delete success!");

  }

?說(shuō)明:刪除就是把這一條鑰匙刪除哦,不是只刪除密碼!

另外的說(shuō)明:如果你的password 是NSData?

查詢: + (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account;

設(shè)置or更新:+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account;

?

下面開(kāi)始淺淺的理解還有對(duì)蘋果API進(jìn)行一點(diǎn)點(diǎn)說(shuō)明吧

1.Keychain 是什么?

keychain 就是放鑰匙柜子!就是蘋果提供給我們的一個(gè)保險(xiǎn)柜。

這篇文章僅針對(duì)iOS。

在iOS中每個(gè)APP 都有屬于自己的Keychain,最常用就是保存用戶的賬戶和密碼,就是記住密碼,放在這里很安全(蘋果負(fù)責(zé)幫我們加密再存起來(lái),如果出了問(wèn)題怪他咯!),假如用NSUserDefault 保存這些秘密數(shù)據(jù),生成的plist文件(就放在那個(gè)Library/Preferences 下)容易被拿到,而且還要自己做加密。

特性:1.當(dāng)app刪除了,又再次重新安裝,這個(gè)保險(xiǎn)柜里的信息還存在哦。 所以當(dāng)你的某女同學(xué)登了APP并保存了密碼,你重裝了APP,如果不刪除記錄,你女票還是可以發(fā)現(xiàn)的。

   2.安全!作為小白的我并不知道它實(shí)際上是存在哪里的。

2.Keychain 組成?

1.組成部分由 ?{N個(gè)標(biāo)簽(屬性) + 一個(gè)重要數(shù)據(jù)} 組成!

2.結(jié)構(gòu)可以看成是一個(gè)字典的形式大概是這樣的: @{@"屬性key1":@"屬性值1",@"屬性keyN":@"屬性值N",@"valueData":@數(shù)據(jù)}?

3.內(nèi)容說(shuō)明:

一個(gè)重要數(shù)據(jù):就是密碼password!

N個(gè)標(biāo)簽:也是屬性,都是用來(lái)表明這條鑰匙的,如我們的serviceName ,account 都是屬性,他們對(duì)應(yīng)的鍵為?kSecAttrAccount 和?kSecAttrAccount,還有系統(tǒng)給我們加的創(chuàng)建時(shí)間,修改時(shí)間等還有l(wèi)abel,type,port,你自己打開(kāi)文件進(jìn)去看看吧,這些標(biāo)簽的任務(wù)就是來(lái)表明這條鑰匙是獨(dú)一無(wú)二的。?

3.原始API操作

先來(lái)看看幾個(gè)API

添加鑰匙:        OSStatus SecItemAdd(CFDictionaryRef attributes, CFTypeRef * __nullable CF_RETURNS_RETAINED result)

查詢密碼與查詢標(biāo)簽:   ??OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef * __nullable CF_RETURNS_RETAINED result)

更新鑰匙信息:   ? ? ? ? ? OSStatus SecItemUpdate(CFDictionaryRef query,?CFDictionaryRef attributesToUpdate)

刪除鑰匙:        OSStatus SecItemDelete(CFDictionaryRef query)

先說(shuō)明一下 這些API的關(guān)鍵在于1.是理解和配置好這個(gè)操作字典 2.注意返回的OSStatus 狀態(tài)?3.CF對(duì)象與OC 之間的bridge

1.先來(lái)一發(fā)查找 ?

過(guò)程:

1.(關(guān)鍵)先配置一個(gè)操作字典內(nèi)容有:

kSecAttrService(屬性),kSecAttrAccount(屬性) 這些屬性or標(biāo)簽是查找的依據(jù)

kSecReturnData(值為@YES 表明返回類型為data),kSecClass(值為kSecClassGenericPassword 表示重要數(shù)據(jù)為“一般密碼”類型) 這些限制條件是返回結(jié)果類型的依據(jù)

2.然后用查找的API 得到查找狀態(tài)和返回?cái)?shù)據(jù)(密碼)

3.最后如果狀態(tài)成功那么將數(shù)據(jù)(密碼)轉(zhuǎn)換成string 返回

//用原生的API 實(shí)現(xiàn)查詢密碼

- (NSString *)passwordForService:(nonnull NSString *)service account:(nonnull NSString *)account{

//生成一個(gè)查詢用的 可變字典

? ? NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:4];

? ? [dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; //表明為一般密碼可能是證書或者其他東西

? ? [dict setObject:service forKey:(__bridge id)kSecAttrService]; ? ?//輸入service

? ? [dict setObject:account forKey:(__bridge id)kSecAttrAccount]; ?//輸入account

? ? [dict setObject:@YES forKey:(__bridge id)kSecReturnData]; ? ? //返回Data

//查詢 ? ?

? ? OSStatus status = -1;

? ? CFTypeRef result = NULL;

? ? status = SecItemCopyMatching((__bridge CFDictionaryRef)dict,&result);//核心API?查找是否匹配?和返回密碼!

? ? if (status != errSecSuccess) { //判斷狀態(tài)

? ? ? ? return nil;

? ? }

//返回?cái)?shù)據(jù)

? ? NSString *password = [[NSString alloc] initWithData:(__bridge_transfer NSData *)result encoding:NSUTF8StringEncoding];//轉(zhuǎn)換成string

? ? return password;

}

說(shuō)明:其實(shí)關(guān)鍵就在于這個(gè)操作字典的配置上!

2.添加&更新

說(shuō)明:當(dāng)添加的時(shí)候我們一般需要判斷一下當(dāng)前鑰匙串里面是否已經(jīng)存在我們要添加的鑰匙。如果已經(jīng)存在我們就更新好了,不存在再添加,所以這兩個(gè)操作一般寫成一個(gè)函數(shù)搞定吧。

過(guò)程關(guān)鍵:1.檢查是否已經(jīng)存在 構(gòu)建的查詢用的操作字典:kSecAttrService,kSecAttrAccount,kSecClass(標(biāo)明存儲(chǔ)的數(shù)據(jù)是什么類型,值為kSecClassGenericPassword 就代表一般的密碼)

   2.添加用的操作字典: kSecAttrService,kSecAttrAccount,kSecClass,kSecValueData

   3.更新用的操作字典1(用于定位需要更改的鑰匙):kSecAttrService,kSecAttrAccount,kSecClass?

        操作字典2(新信息)kSecAttrService,kSecAttrAccount,kSecClass ,kSecValueData

?

//用原生的API 添加一條鑰匙

-(BOOL)addItemWithService:(NSString *)service account:(NSString *)account password:(NSString *)password{

//先查查是否已經(jīng)存在

//構(gòu)造一個(gè)操作字典用于查詢

? ? NSMutableDictionary *searchDict = [[NSMutableDictionary alloc]initWithCapacity:4];

? ? [searchDict setObject:service forKey:(__bridge id)kSecAttrService]; ? ? ? ? ? ? ? ? ? ? ? ? //標(biāo)簽service

? ? [searchDict setObject:account forKey:(__bridge id)kSecAttrAccount]; ? ? ? ? ? ? ? ? ? ? ? ? //標(biāo)簽account

? ? [searchDict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];//表明存儲(chǔ)的是一個(gè)密碼

? ??

? ? OSStatus status = -1;

? ? CFTypeRef result =NULL;

? ? status = SecItemCopyMatching((__bridge CFDictionaryRef)searchDict, &result);

? ? if (status == errSecItemNotFound) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //沒(méi)有找到則添加

? ? ? ? NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];? ? //password 轉(zhuǎn)換為 NSData

? ? ? ? [searchDict setObject:passwordData forKey:(__bridge id)kSecValueData]; ? ? ? //添加密碼? ? ??

? ? ? ? status = SecItemAdd((__bridge CFDictionaryRef)searchDict, NULL); ? ? ? ? ? ? //!!!!!關(guān)鍵的添加API

? ? }else if (status == errSecSuccess){? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //成功找到,說(shuō)明鑰匙已經(jīng)存在則進(jìn)行更新

? ? ? ? NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];? ? //password 轉(zhuǎn)換為 NSData

? ? ? ? NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:searchDict];

? ? ? ? [dict setObject:passwordData forKey:(__bridge id)kSecValueData]; ? ? ? ? ? ? //添加密碼? ? ?

? ? ? ? status = SecItemUpdate((__bridge CFDictionaryRef)searchDict, (__bridge CFDictionaryRef)dict);//!!!!關(guān)鍵的更新API

? ? }

? ? return (status == errSecSuccess);

}

?

?

?

轉(zhuǎn)載:http://www.cnblogs.com/m4abcd/p/5242254.html

轉(zhuǎn)載于:https://www.cnblogs.com/sunjianfei/p/6560309.html

總結(jié)

以上是生活随笔為你收集整理的SSKeychain的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。