精华内容
下载资源
问答
  • KeyChain

    2019-09-19 22:28:11
    写在篇头:本文结合jijunyuan的ios中KeyChain用途一文 略作改动而成,再次感谢那些乐于分享的人。 一、在应用间利用KeyChain共享数据 我们可以把KeyChain理解为一个Dictionary,所有数据都以key-value的形式存储...

    写在篇头:本文结合jijunyuan的ios中KeyChain用途一文 略作改动而成,再次感谢那些乐于分享的人。

    一、在应用间利用KeyChain共享数据

           我们可以把KeyChain理解为一个Dictionary,所有数据都以key-value的形式存储,可以对这个Dictionary进行add、update、get、delete这四个操作。对于每一个应用来说,KeyChain都有两个访问区,私有区和公共区。私有区是一个sandbox,本程序存储的任何数据都对其他程序不可见。而要想在将存储的内容放在公共区,需要先声明公共区的名称,官方文档管这个名称叫“keychain access group”,声明的方法是新建一个plist文件,plist文件名字随便起,内容如下:
     
     
    “yourAppID.com.yourCompany.whatever”就是你要起的公共区名称,除了whatever字段可以随便定之外,其他的都必须如实填写。这个文件的路径要配置在 Project->build setting->Code Signing Entitlements里,否则公共区无效, 配置好后,须用你正式的证书签名编译才可通过(Project->Capebilities->Keychain Sharing -> step 显示两个√ 第一个显示“×” 可以点击fixit ,否则xcode会弹框告诉你code signing有问题。所以,苹果限制了你只能同公司的产品共享KeyChain数据,别的公司访问不了你公司产品的KeyChain。
     
    二、保存私密信息
    iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储。相对于NSUserDefaults、文件保存等一般方式,keychain保存更为安全,而且keychain里保存的信息不会因App被删除而丢失,所以在重装App后,keychain里的数据还能使用。
     
    在应用里使用使用keyChain,我们需要导入Security.framework ,keychain的操作接口声明在头文件SecItem.h里。直接使用SecItem.h里方法操作keychain,需要写的代码较为复杂,为减轻咱们程序员的开发,我们可以使用一些已经封装好了的工具类,下面我会简单介绍下我用过的两个工具类:KeychainItemWrapper和SFHFKeychainUtils。
     
    (一)KeychainItemWrapper是apple官方例子“GenericKeychain”里一个访问keychain常用操作的封装类,在官网上 下载了GenericKeychain项目后,只需要把“KeychainItemWrapper.h”和“KeychainItemWrapper.m”拷贝到我们项目,并导入Security.framework 。KeychainItemWrapper的用法:
     
    /** 初始化一个保存用户帐号的KeychainItemWrapper */
    KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"Account Number"
                                                                       accessGroup:@"YOUR_APP_ID_HERE.com.yourcompany.AppIdentifier"];  
     
    //保存帐号 
    [
    wrapper setObject:@"<帐号>" forKey:(id)kSecAttrAccount];    // 非ARC环境
    wrapper setObject:@"<帐号>" forKey:(__bridge id)kSecAttrAccount]; // ARC环境 以下方法类同,不在重复
     
    //保存密码
    [
    wrapper setObject:@"<帐号密码>" forKey:(id)kSecValueData];    
     
    //从keychain里取出帐号密码
    NSString *password = [wrapper objectForKey:(id)kSecValueData];      
     
    //清空设置
    [
    wrapper resetKeychainItem];
    其中方法“- (void)setObject:(id)inObject forKey:(id)key;”里参数“forKey”的值应该是Security.framework 里头文件“SecItem.h”里定义好的key,用其他字符串做key程序会崩溃!
     
     
    (二)SFHFKeychainUtils 提供了在 iOS keychain中安全的存储密码的工具
     
    下载地址https://github.com/ldandersen/scifihifi-iphone/tree/master/security
     
    1、引入Security.frameWork框架。
     
    2、引入头文件:SFHKeychainUtils.h.
     
    3、存密码:
     
    [SFHFKeychainUtils storeUsername:@"dd" andPassword:@"aa"forServiceName:SERVICE_NAME updateExisting:1 error:nil];
     
    [SFHFKeychainUtils deleteItemForUsername:@"dd" andServiceName:SERVICE_NAME error:nil];
     
    4、取密码:
     
    NSString *passWord =  [SFHFKeychainUtils getPasswordForUsername:@"dd"andServiceName:SERVICE_NAME error:nil];

    转载于:https://my.oschina.net/u/1441580/blog/283915

    展开全文
  • Keychain

    千次阅读 2016-10-11 20:45:31
    【http://blog.sheliw.com/blog/2015/02/16/keychain/】 Keychain FEB 16TH, 2015 3:27 ...什么是Keychain?...根据苹果的介绍,iOS设备中的Keychain是一个安全的存储容器,可以用来...苹果自己用keychain来保存Wi

    【http://blog.sheliw.com/blog/2015/02/16/keychain/】

    Keychain

    FEB 16TH2015 3:27 PM

    什么是Keychain?

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

    如果我们手动把自己的私密信息加密,然后通过写文件保存在本地,再从本地取出不仅麻烦,而且私密信息也会随着App的删除而丢失。iOS的Keychain能完美的解决这些问题。并且从iOS 3.0开始,Keychain还支持跨程序分享。这样就极大的方便了用户。省去了很多要记忆密码的烦恼。

    Structure of a Keychain

    Keychain内部可以保存很多的信息。每条信息作为一个单独的keychain item,keychain item一般为一个字典,每条keychain item包含一条data和很多attributes。举个例子,一个用户账户就是一条item,用户名可以作为一个attribute , 密码就是data。 keychain虽然是可以保存15000条item,每条50个attributes,但是苹果工程师建议最好别放那么多,存几千条密码,几千字节没什么问题。

    如果把keychain item的类型指定为需要保护的类型比如password或者private key,item的data会被加密并且保护起来,如果把类型指定为不需要保护的类型,比如certificates,item的data就不会被加密。

    item可以指定为以下几种类型:

    • extern CFTypeRef kSecClassGenericPassword
    • extern CFTypeRef kSecClassInternetPassword
    • extern CFTypeRef kSecClassCertificate
    • extern CFTypeRef kSecClassKey
    • extern CFTypeRef kSecClassIdentity OSX_AVAILABLE_STARTING(MAC_10_7, __IPHONE_2_0);

    Keychain的用法

    首先导入Security.framework 。

    Keychain的API提供以下几个函数来操作Keychain

    • SecItemAdd 添加一个keychain item
    • SecItemUpdate 修改一个keychain item
    • SecItemCopyMatching 搜索一个keychain item
    • SecItemDelete 删除一个keychain item

    也可以参考以下这段简单的代码来了解下Keychain API的用法。

    
    - (NSMutableDictionary *)newSearchDictionary:(NSString *)identifier {
        NSMutableDictionary *searchDictionary = [[NSMutableDictionary alloc] init];
        //指定item的类型为GenericPassword
        [searchDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
        
        //类型为GenericPassword的信息必须提供以下两条属性作为unique identifier
        [searchDictionary setObject:encodedIdentifier forKey:(id)kSecAttrAccount];
        [searchDictionary setObject:encodedIdentifier forKey:(id)kSecAttrService];
        
        return searchDictionary;
    }
    - (NSData *)searchKeychainCopyMatching:(NSString *)identifier {
        NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];
        
        //在搜索keychain item的时候必须提供下面的两条用于搜索的属性
        //只返回搜索到的第一条item
        [searchDictionary setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
        //返回item的kSecValueData
        [searchDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
        
        NSData *result = nil;
        OSStatus status = SecItemCopyMatching((CFDictionaryRef)searchDictionary,
                                              (CFTypeRef *)&result);
        [searchDictionary release];
        return result;
    }
    - (BOOL)createKeychainValue:(NSString *)password forIdentifier:(NSString *)identifier {
        NSMutableDictionary *dictionary = [self newSearchDictionary:identifier];
        
        NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
        [dictionary setObject:passwordData forKey:(id)kSecValueData];
        
        OSStatus status = SecItemAdd((CFDictionaryRef)dictionary, NULL);
        [dictionary release];
        if (status == errSecSuccess) {
            return YES;
        }
        return NO;
    }
    - (BOOL)updateKeychainValue:(NSString *)password forIdentifier:(NSString *)identifier {
        NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];
        
        NSMutableDictionary *updateDictionary = [[NSMutableDictionary alloc] init];
        NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
        [updateDictionary setObject:passwordData forKey:(id)kSecValueData];
        
        OSStatus status = SecItemUpdate((CFDictionaryRef)searchDictionary,
                                        (CFDictionaryRef)updateDictionary);
        
        [searchDictionary release];
        [updateDictionary release];
        
        if (status == errSecSuccess) {
            return YES;
        }
        return NO;
    }
    - (void)deleteKeychainValue:(NSString *)identifier {
        NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier];
        SecItemDelete((CFDictionaryRef)searchDictionary);
        [searchDictionary release];
    }
    

    Keychain API的用法稍微有点复杂。不过Apple自己也提供了一个封装了Keychain API的类: KeychainItemWrapper https://developer.apple.com/library/ios/samplecode/GenericKeychain/Introduction/Intro.html 虽然这个类封装了Keychain的API,但是不仅代码写的很不容易理解,而且里面也有不少的Bug。所以还是不建议使用。 目前发现这个类的1.2版存在的Bug为:

    1. 如果需要某个keychain item支持iCloud备份,添加kSecAttrSynchronizable属性之后,它并没有在第二次更新item或者搜索item的时候加上这一条,所以导致item已经存在但是它却获取不到。
    2. 类型为GenericPassword的item必须使用kSecAttrAccount和kSecAttrService作为主要的key,但是这个类仅仅以kSecAttrGeneric作主要的key。所以在用它添加item的时候容易出现重复添加的错误。

    每种类型的Keychain item都有不同的键作为主要的Key也就是唯一标示符用于搜索,更新和删除,Keychain内部不允许添加重复的Item。

    keychain item的类型,也就是kSecClass键的值 主要的Key
    kSecClassGenericPassword kSecAttrAccount,kSecAttrService
    kSecClassInternetPassword kSecAttrAccount, kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol,kSecAttrAuthenticationType, kSecAttrPortkSecAttrPath
    kSecClassCertificate kSecAttrCertificateType, kSecAttrIssuerkSecAttrSerialNumber
    kSecClassKey kSecAttrApplicationLabel, kSecAttrApplicationTag, kSecAttrKeyType,kSecAttrKeySizeInBits, kSecAttrEffectiveKeySize
    kSecClassIdentity kSecClassKey,kSecClassCertificate

    Keychain的备份

    1. iOS的Keychain由系统管理并且进行加密,Keychain内的信息会随着iPhone的数据一起备份。但是kSecAttrAccessible 属性被设置为后缀是ThisDeviceOnly的数据会被以硬件相关的密钥(key)加密。并且不会随着备份移动至其他设备。

      kSecAttrAccessiblein变量用来指定这条信息的保护程度。我们需要对这个选项特别注意,并且使用最严格的选项。这个键(key)可以设置6种值。

      • CFTypeRef kSecAttrAccessibleWhenUnlocked;
      • CFTypeRef kSecAttrAccessibleAfterFirstUnlock;
      • CFTypeRef kSecAttrAccessibleAlways;
      • CFTypeRef kSecAttrAccessibleWhenUnlockedThisDeviceOnly;
      • CFTypeRef kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
      • CFTypeRef kSecAttrAccessibleAlwaysThisDeviceOnly;

      从iOS5.0开始kSecAttrAccessible默认为kSecAttrAccessibleWhenUnlocked。

    2. Keychain从iOS7.0开始也支持iCloud备份。把kSecAttrSynchronizable属性设置为@YES,这样后Keychain就能被iCloud备份并且跨设备分享。

      不过在添加kSecAttrSynchronizable属性后,这条属性会被作为每条Keychain Item的主要的Key之一,所以在搜索,更新,删除的时候如果查询字典内没有这一条属性,item就匹配不到。

    Keychain Access Group

    Keychain通过provisioning profile来区分不同的应用,provisioning文件内含有应用的bundle id和添加的access groups。不同的应用是完全无法访问其他应用保存在Keychain的信息,除非指定了同样的access group。指定了同样的group名称后,不同的应用间就可以分享保存在Keychain内的信息。

    Keychain Access Group的使用方法:

    1. 首先要在Capabilities下打开工程的Keychain Sharing按钮。然后需要分享Keychain的不同应用添 加相同的Group名称。Xcode6以后Group可以随便命名,不需要加AppIdentifierPrefix前缀,并且Xcode会在以entitlements结尾的文件内自动添加所有Group名称,然后在每一个Group前自动加上$(AppIdentifierPrefix)前缀。虽然文档内提到还需要添加一个包含group的.plist文件,其实它和.entitlements文件是同样的作用,所以不需要重复添加。 但是每个不同的应用第一条Group最好以自己的bundleID命名,因为如果entitlements文件内已经有Keychain Access Groups数组后item的Group属性默认就为数组内的第一条Grop。

    2. 需要支持跨设备分享的Keychain item添加一条AccessGroup属性,不过代码里Group名称一定要加上AppIdentifierPrefix前缀。 [searchDictionary setObject:@“AppIdentifierPrefix.UC.testWriteKeychainSuit” forKey:(id)kSecAttrAccessGroup];如果要在app内部存私有的信息,group置为自己的bundleID即可,如果entitlements文件内没有指定Keychain Access Groups数组。那group也可以置为nil,这样默认也会以自己的bundleID作为Group。

    Keychain的安全性

    Keychain内部的数据会自动加密。如果设备没有越狱并且不暴力破解,keychain确实很安全。但是越狱后的设备,keychain就很危险了。

    通过上面的一些信息我们已经知道访问keychain里面的数据需要和app一样的证书或者获得access group的名称。设备越狱后相当于对苹果做签名检查的地方打了个补丁,伪造一个证书的app也能正常使用,并且加上Keychain Dumper这些工具获取Keychain内的信息会非常容易。

    使用keychain需要注意的问题

    1. 当我们不支持Keychain Access Group,并且没有entitlement文件时,keychain默认以bundle id为group。如果我们在版本更新的时候改变了bundle id,那么新版本就访问不了旧版本的keychain信息了。解决办法是从一开始我们就打开KeychainSharing,添加Keychain Access Group,并且指定每条keychain Item的group,私有的信息就指定app的bundle id为它的group。
    2. 代码内Access group名称一定要有AppIdentifierPrefix前缀。
    3. Keychain是基于数据库存储,不允许添加重复的条目。所以每条item都必须指定对应的唯一标识符也就是那些主要的key,如果Key指定不正确,可能会出现添加后查找不到的问题。
    4. kSecAttrSynchronizable也会作为主要的key之一。它的value值默认为No,如果之前添加的item此条属性为YES,在搜索,更新,删除的时候必须添加此条属性才能查找到之前添加的item。
    5. Kechain item字典内添加自定义key时会出现参数不合法的错误。

    总结

    keychain很强大,是一个值得利用的工具,我们可以在保存密码或者证书的时候使用keychain,并且支持不同应用分享Keychain内的信息,或者支持iCloud备份跨设备分享,但是越狱版应用还是不建议使用。


    展开全文
  • keychain

    2017-01-23 21:53:36
    keyChain是苹果提供的一种安全性高的容器,可以用来存储一些私密的信息...app被卸载之后就会丢失,但是keyChain存储就不会有这种问题,除非你手动清除,本质是一个SQLite数据库,可以通过设置不同的标识来存储不同的用

    keyChain是苹果提供的一种安全性高的容器,可以用来存储一些私密的信息,比如用户名密码等,苹果用它来存储wifi密码等信息,keyChain会把用户信息存储在本地,而不是像NSUserDefault一样存储在app的沙盒里面,对于沙盒中存储的数据,app被卸载之后就会丢失,但是keyChain存储就不会有这种问题,除非你手动清除,本质是一个SQLite数据库,可以通过设置不同的标识来存储不同的用户信息,一条item对应一条用户信息,也可以通过设置access Group来在应用之间共享数据,在iOS10中,真机测试没有问题,但是模拟器测试就会崩溃,在project设置中开启keyChain share就可以.

    展开全文
  • Keychain-源码

    2021-03-30 03:49:26
    Keychain
  • s to https://github.com/keybase/go-keychain that will let us entirely replace our long-ago-forked custom keychain interaction code. So much joy in this diff. <p>...
  • KeychainAccess 是 Keychain 简单的 Swift 封装,支持 iOS 和 OS X。
  • 封装keychain

    2017-06-23 12:09:32
    封装keychain,操作简单,用法灵活,可根据自己项目需要添加存储的属性。
  • Keychain problem

    2020-12-31 01:17:13
    Unfortunately Passionfruit crashes when opening keychain that has binary data. In my case application had stored AES encrypted data in keychain and whenever i tried to open them Passionfruit was ...
  • keychain_dumper

    2018-11-08 13:04:29
    keychain_dumper
  • keychain error

    2020-12-03 00:25:00
    ✔︎ Token saved to keychain. $ ghi list ⠄security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain. # Authorization required. Please run 'ghi config --auth <...
  • Keychain integration

    2020-12-07 04:12:49
    <div><p>It would be nice to be able to save the encryptr password in osx keychain.</p><p>该提问来源于开源项目:SpiderOak/Encryptr</p></div>
  • t add the new keychain to the keychain search list so nothing can use it. The added command here manually adds the newly created keychain to the search list while keeping the login keychain on it.</p>...
  • Keychain Migration

    2020-11-30 04:58:23
    s an attempt at migrating the token that is stored in the keychain to the new keychain. <p>This is pretty hard to test, but I was able to see it working by: <ul><li>Installing Simplenote from the app ...
  • Keychain issue

    2020-12-02 23:02:41
    <div><p>Result: [OPERATION FAILED]:Unable to retrieve password from the keychain store. <p>I know why I am getting this error (new laptop old project folder) <p>How can I force it to relogin? </p><p>...
  • iOS KeyChain

    2014-12-02 20:15:09
    对于一些私密信息,比如密码、证书等等,就需要使用更为安全的keychain了。keychain里保存的信息不会因App被删除而丢失,在用户重新安装App后依然有效,数据还在。
  • Keychain support

    2020-11-29 19:47:58
    <ul><li>[ ] Support multiple passwords stored in Keychain</li><li>[ ] Suggest them in the password field, compression and extraction (-Issle #468)</li><li>[ ] Option to try the stored passwords in ...
  • 【共享keychain数据】当往keychain中插入数据时,默认的kSecAttrAccessGroup就是App自身的BundleID。【官方文档】You can add a keychain-access-groups entitlement to the application and, in the entitlement ...

    【共享keychain数据】

    当往keychain中插入数据时,默认的 kSecAttrAccessGroup就是App自身的BundleID。

    【官方文档】

    You can add a keychain-access-groups entitlement to the application and, in the entitlement property list file, specify an array of keychain access groups to which the application belongs.

    可以在entitlements文件中指定keychain-access-groups属性。此属性下定义了一组字符串标识。

    If you add such a property-list file to the application bundle, then the access group corresponding to the application-identifier entitlement is treated as the last element in the access groups array.

    如果添加了keychain-access-group选项,那原有的app BundleID会被加入到最后一项。

    If you do not include the kSecAttrAccessGroup key in the attributes dictionary when you call the SecItemAdd function to add an item to the keychain, the function uses the first access group in the array by default.

    如果没有指定kSecAttrAccessGroup键,SecItemAdd函数默认使用第一个group值。

    If there is no kSecAttrAccessGroup key in the attributes dictionary and there is no keychain-access-groups entitlement in the application bundle, then the access group of a newly created item is the value of the application-identifier entitlement.

    如果没有指定kSecAttrAccessGroup键,也没有设置keychain-acess-group选项,则使用App BundleID作为kSecAttrAccessGroup的值。

    【其它要求】

    When you want to create an app that can share keychain access with an existing app you need to make sure that you use the bundle seed ID of the existing app. You do this when you create the new App ID in the iPhone Provisioning Portal. Instead of generating a new value you select the existing value from the list of all your previous bundle seed IDs.

    若要共享keychain数据,两个App的bundle seed id必须相同。

    The keychain access group can be named pretty much anything you want as long as it starts with the bundle seed ID.

    keychain-acess-group必须以同样的bundle seed id开头。

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,898
精华内容 2,359
热门标签
关键字:

keychain