ios Keychain存储

作者: 像小强一样活着 | 来源:发表于2017-02-03 11:22 被阅读237次


    iOS设备中的Keychain是一个安全的存储容器,可以用来为不同应用保存敏感信息比如用户名,密码,网络密码,认证令牌。苹果自己用keychain来保存Wi-Fi网络密码,VPN凭证等等。它是一个sqlite数据库.

    位于/private/var/Keychains/keychain-2.db,其保存的所有数据都是加密过的。模拟器下keychain文件路径:~/Library/Application Support/iPhone Simulator/4.3/Library/Keychains

    keychain里保存的信息不会因App被删除而丢失,在用户重新安装App后依然有效,数据还在。

    关于备份,�只会备份数据,到那时不会备份设备的密钥,换句话说,即使拿到数据,也没有办法解密里面的内容。


     密钥类型

    密钥类型的键    CFTypeRef kSecClass

    密钥类型的值:

    //CFTypeRef kSecClassGenericPassword            //一般密码

    //CFTypeRef kSecClassInternetPassword          //网络密码

    //CFTypeRef kSecClassCertificate                //证书

    //CFTypeRef kSecClassKey                        //密钥

    //CFTypeRef kSecClassIdentity                  //身份证书(带私钥的证书)

    不同类型的钥匙串项对应的属性不同

    1.一般密码 kSecClassGenericPassword

    a.对应属性

    //kSecAttrAccessible

    //kSecAttrAccessGroup

    //kSecAttrCreationDate

    //kSecAttrModificationDate

    //kSecAttrDescription

    //kSecAttrComment

    //kSecAttrCreator

    //kSecAttrType

    //kSecAttrLabel

    //kSecAttrIsInvisible

    //kSecAttrIsNegative

    //kSecAttrAccount

    //kSecAttrService

    //kSecAttrGeneric

    2.网络密码  kSecClassInternetPassword

    a.对应属性

    //kSecAttrAccessible

    //kSecAttrAccessGroup

    //kSecAttrCreationDate

    //kSecAttrModificationDate

    //kSecAttrDescription

    //kSecAttrComment

    //kSecAttrCreator

    //kSecAttrType

    //kSecAttrLabel

    //kSecAttrIsInvisible

    //kSecAttrIsNegative

    //kSecAttrAccount

    //kSecAttrSecurityDomain

    //kSecAttrServer

    //kSecAttrProtocol

    //kSecAttrAuthenticationType

    //kSecAttrPort

    //kSecAttrPath

    3.证书  kSecClassCertificate

    c.对应属性

    //kSecAttrAccessible

    //kSecAttrAccessGroup

    //kSecAttrCertificateType

    //kSecAttrCertificateEncoding

    //kSecAttrLabel

    //kSecAttrSubject

    //kSecAttrIssuer

    //kSecAttrSerialNumber

    //kSecAttrSubjectKeyID

    //kSecAttrPublicKeyHash

    4.密钥   kSecClassKey

    d.对应属性

    //kSecAttrAccessible

    //kSecAttrAccessGroup

    //kSecAttrKeyClass

    //kSecAttrLabel

    //kSecAttrApplicationLabel

    //kSecAttrIsPermanent

    //kSecAttrApplicationTag

    //kSecAttrKeyType

    //kSecAttrKeySizeInBits

    //kSecAttrEffectiveKeySize

    //kSecAttrCanEncrypt

    //kSecAttrCanDecrypt

    //kSecAttrCanDerive

    //kSecAttrCanSign

    //kSecAttrCanVerify

    //kSecAttrCanWrap

    //kSecAttrCanUnwrap


     证书属性

    1.私钥属性

    键  CFTypeRef kSecAttrAccessible           //可访问性 类型透明

    //          CFTypeRef kSecAttrAccessibleWhenUnlocked;                  //解锁可访问,备份

    //          CFTypeRef kSecAttrAccessibleAfterFirstUnlock;           //第一次解锁后可访问,备份

    //          CFTypeRef kSecAttrAccessibleAlways;                   //一直可访问,备份

    //          CFTypeRef kSecAttrAccessibleWhenUnlockedThisDeviceOnly;    //解锁可访问,不备份

    //          CFTypeRef kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;//第一次解锁后可访问,不备份

    //          CFTypeRef kSecAttrAccessibleAlwaysThisDeviceOnly;          //一直可访问,不备份

    //CFTypeRef kSecAttrCreationDate;      //创建日期          CFDateRef

    //CFTypeRef kSecAttrModificationDate;  //最后一次修改日期  CFDateRef

    //CFTypeRef kSecAttrDescription;      //描述            CFStringRef

    //CFTypeRef kSecAttrComment;          //注释            CFStringRef

    //CFTypeRef kSecAttrCreator;          //创建者            CFNumberRef(4字符,如'aLXY')

    //CFTypeRef kSecAttrType;              //类型            CFNumberRef(4字符,如'aTyp')

    //CFTypeRef kSecAttrLabel;            //标签(给用户看)    CFStringRef

    //CFTypeRef kSecAttrIsInvisible;      //是否隐藏          CFBooleanRef(kCFBooleanTrue,kCFBooleanFalse)

    //CFTypeRef kSecAttrIsNegative;        //是否具有密码      CFBooleanRef(kCFBooleanTrue,kCFBooleanFalse)此项表示当前的item是否只是一个占位项,或者说是只有key没有value。

    //CFTypeRef kSecAttrAccount;          //账户名            CFStringRef

    //CFTypeRef kSecAttrService;          //所具有服务        CFStringRef

    //CFTypeRef kSecAttrGeneric;          //用户自定义内容      CFDataRef

    //CFTypeRef kSecAttrSecurityDomain;    //网络安全域        CFStringRef

    //CFTypeRef kSecAttrServer;            //服务器域名或IP地址  CFStringRef

    //键 CFTypeRef kSecAttrProtocol;               //协议类型 CFNumberRef

     值

    //          CFTypeRef kSecAttrProtocolFTP;        

    //          CFTypeRef kSecAttrProtocolFTPAccount; 

    //          CFTypeRef kSecAttrProtocolHTTP;        

    //          CFTypeRef kSecAttrProtocolIRC;        

    //          CFTypeRef kSecAttrProtocolNNTP;        

    //          CFTypeRef kSecAttrProtocolPOP3;        

    //          CFTypeRef kSecAttrProtocolSMTP;        

    //          CFTypeRef kSecAttrProtocolSOCKS;      

    //          CFTypeRef kSecAttrProtocolIMAP;        

    //          CFTypeRef kSecAttrProtocolLDAP;        

    //          CFTypeRef kSecAttrProtocolAppleTalk;  

    //          CFTypeRef kSecAttrProtocolAFP;        

    //          CFTypeRef kSecAttrProtocolTelnet;      

    //          CFTypeRef kSecAttrProtocolSSH;        

    //          CFTypeRef kSecAttrProtocolFTPS;        

    //          CFTypeRef kSecAttrProtocolHTTPS;      

    //          CFTypeRef kSecAttrProtocolHTTPProxy;  

    //          CFTypeRef kSecAttrProtocolHTTPSProxy;  

    //          CFTypeRef kSecAttrProtocolFTPProxy;    

    //          CFTypeRef kSecAttrProtocolSMB;        

    //          CFTypeRef kSecAttrProtocolRTSP;        

    //          CFTypeRef kSecAttrProtocolRTSPProxy;  

    //          CFTypeRef kSecAttrProtocolDAAP;        

    //          CFTypeRef kSecAttrProtocolEPPC;        

    //          CFTypeRef kSecAttrProtocolIPP;        

    //          CFTypeRef kSecAttrProtocolNNTPS;     

    //          CFTypeRef kSecAttrProtocolLDAPS;      

    //          CFTypeRef kSecAttrProtocolTelnetS;    

    //          CFTypeRef kSecAttrProtocolIMAPS;      

    //          CFTypeRef kSecAttrProtocolIRCS;        

    //          CFTypeRef kSecAttrProtocolPOP3S;      

    //键 CFTypeRef kSecAttrAuthenticationType        

     认证类型 CFNumberRef

     值

    //          CFTypeRef kSecAttrAuthenticationTypeNTLM;        //

    //          CFTypeRef kSecAttrAuthenticationTypeMSN;        //

    //          CFTypeRef kSecAttrAuthenticationTypeDPA;        //

    //          CFTypeRef kSecAttrAuthenticationTypeRPA;        //

    //          CFTypeRef kSecAttrAuthenticationTypeHTTPBasic;  //

    //          CFTypeRef kSecAttrAuthenticationTypeHTTPDigest;  //

    //          CFTypeRef kSecAttrAuthenticationTypeHTMLForm;    //

    //          CFTypeRef kSecAttrAuthenticationTypeDefault;    //

    //CFTypeRef kSecAttrPort;                //网络端口          CFNumberRef

    //CFTypeRef kSecAttrPath;                //访问路径          CFStringRef

    //CFTypeRef kSecAttrSubject;              //X.500主题名称      CFDataRef

    //CFTypeRef kSecAttrIssuer;              //X.500发行者名称    CFDataRef

    //CFTypeRef kSecAttrSerialNumber;        //序列号            CFDataRef

    //CFTypeRef kSecAttrSubjectKeyID;        //主题ID            CFDataRef

    //CFTypeRef kSecAttrPublicKeyHash;        //公钥Hash值        CFDataRef

    //CFTypeRef kSecAttrCertificateType;      //证书类型            CFNumberRef

    //CFTypeRef kSecAttrCertificateEncoding;  //证书编码类型        CFNumberRef

    //CFTypeRef kSecAttrKeyClass             //加密密钥类  CFTypeRef

    //          CFTypeRef kSecAttrKeyClassPublic;    //公钥

    //          CFTypeRef kSecAttrKeyClassPrivate;    //私钥

    //          CFTypeRef kSecAttrKeyClassSymmetric;  //对称密钥

    //CFTypeRef kSecAttrApplicationLabel;  //标签(给程序使用)          CFStringRef(通常是公钥的Hash值)

    //CFTypeRef kSecAttrIsPermanent;      //是否永久保存加密密钥      CFBooleanRef

    //CFTypeRef kSecAttrApplicationTag;    //标签(私有标签数据)        CFDataRef

    //CFTypeRef kSecAttrKeyType  //加密密钥类型(算法)  CFNumberRef

     值

    //          extern const CFTypeRef kSecAttrKeyTypeRSA;

    //CFTypeRef kSecAttrKeySizeInBits;    //密钥总位数              CFNumberRef

    //CFTypeRef kSecAttrEffectiveKeySize;  //密钥有效位数              CFNumberRef

    //CFTypeRef kSecAttrCanEncrypt;        //密钥是否可用于加密        CFBooleanRef

    //CFTypeRef kSecAttrCanDecrypt;        //密钥是否可用于加密        CFBooleanRef

    //CFTypeRef kSecAttrCanDerive;        //密钥是否可用于导出其他密钥  CFBooleanRef

    //CFTypeRef kSecAttrCanSign;          //密钥是否可用于数字签名      CFBooleanRef

    //CFTypeRef kSecAttrCanVerify;        //密钥是否可用于验证数字签名  CFBooleanRef

    //CFTypeRef kSecAttrCanWrap;          //密钥是否可用于打包其他密钥  CFBooleanRef

    //CFTypeRef kSecAttrCanUnwrap;        //密钥是否可用于解包其他密钥  CFBooleanRef

    //CFTypeRef kSecAttrAccessGroup;      //访问组                  CFStringRef

    搜索

    //CFTypeRef kSecMatchPolicy;                //指定策略            SecPolicyRef

    //CFTypeRef kSecMatchItemList;              //指定搜索范围        CFArrayRef(SecKeychainItemRef, SecKeyRef, SecCertificateRef, SecIdentityRef,CFDataRef)数组内的类型必须唯一。仍然会搜索钥匙串,但是搜索结果需要与该数组取交集作为最终结果。

    //CFTypeRef kSecMatchSearchList;            //

    //CFTypeRef kSecMatchIssuers;                //指定发行人数组      CFArrayRef

    //CFTypeRef kSecMatchEmailAddressIfPresent;  //指定邮件地址        CFStringRef

    //CFTypeRef kSecMatchSubjectContains;        //指定主题            CFStringRef

    //CFTypeRef kSecMatchCaseInsensitive;        //指定是否不区分大小写  CFBooleanRef(kCFBooleanFalse或不提供此参数,区分大小写;kCFBooleanTrue,不区分大小写)

    //CFTypeRef kSecMatchTrustedOnly;            //指定只搜索可信证书    CFBooleanRef(kCFBooleanFalse或不提供此参数,全部证书;kCFBooleanTrue,只搜索可信证书)

    //CFTypeRef kSecMatchValidOnDate;            //指定有效日期        CFDateRef(kCFNull表示今天)

    //CFTypeRef kSecMatchLimit;                  //指定结果数量        CFNumberRef(kSecMatchLimitOne;kSecMatchLimitAll)

    //CFTypeRef kSecMatchLimitOne;              //首条结果

    //CFTypeRef kSecMatchLimitAll;              //全部结果

    列表

    //CFTypeRef kSecUseItemList;  //CFArrayRef(SecKeychainItemRef, SecKeyRef, SecCertificateRef, SecIdentityRef,CFDataRef)数组内的类型必须唯一。用户提供用于查询的列表。当这个列表被提供的时候,不会再搜索钥匙串。

     返回值类型

    //可以同时指定多种返回值类型

    //CFTypeRef kSecReturnData;          //返回数据(CFDataRef)                  CFBooleanRef

    //CFTypeRef kSecReturnAttributes;    //返回属性字典(CFDictionaryRef)        CFBooleanRef

    //CFTypeRef kSecReturnRef;            //返回实例(SecKeychainItemRef, SecKeyRef, SecCertificateRef, SecIdentityRef, or CFDataRef)        CFBooleanRef

    //CFTypeRef kSecReturnPersistentRef;  //返回持久型实例(CFDataRef)            CFBooleanRef

    写入值类型

    //CFTypeRef kSecValueData;

    //CFTypeRef kSecValueRef;

    //CFTypeRef kSecValuePersistentRef;

    -------------------------------------------------------------------

    简单实现:

    在”Build Phases“中导入库"Security.framework"

    + (BOOL)save:(NSString*)service data:(id)data;

    + (id)load:(NSString*)service;

    + (void)delete:(NSString*)service;

    + (NSMutableDictionary*) getKeychainQuery: (NSString*)service {

    return [NSMutableDictionary dictionaryWithObjectsAndKeys:

    (id)kSecClassGenericPassword, (id)kSecClass,

    service, (id)kSecAttrService,

    service, (id)kSecAttrAccount,

    (id)kSecAttrAccessibleAfterFirstUnlock, (id)kSecAttrAccessible,

    nil nil];

    }

    + (BOOL) save:(NSString*)service data:(id)data {

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    SecItemDelete((CFDictionaryRef)keychainQuery);

    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];

    return SecItemAdd((CFDictionaryRef)keychainQuery, NULL) == noErr;

    }

    + (id) load:(NSString*)service {

    id ret = NULL;

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];

    [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];

    NSData *keyData = NULL;

    if(SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef*)(void*)&keyData) == noErr) {

    @try {

    ret = [NSKeyedUnarchiver unarchiveObjectWithData:keyData];

    }

    @catch (NSException *exception) {

    NSLog(@"Unarchive of %@ failed: %@", service, exception);

    }

    @finally {

    }

    }

    return ret;

    }

    + (void) delete:(NSString*)service {

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    SecItemDelete((CFDictionaryRef)keychainQuery);

    }

    相关文章

      网友评论

        本文标题:ios Keychain存储

        本文链接:https://www.haomeiwen.com/subject/twawbttx.html