IOS安全编程之Keychain基本概念

有时候我们的程序可能会在iphone上存储一些敏感或认证信息,比如登录密码,网站认证书,用于信息加解密的私钥等。有些信息不能以明文来存储,最好是我们能把这些信息加密起来,然后存到一个安全的地方。

那么我们把他们放在那里呢?IOS系统为我们提供了一个保险柜——Keychain即钥匙串。Keychain提供了一种机制,让我们可以将这些敏感数据存放到Keychain中,对于有必要加密的信息,会被IOS自动加密(即使是在做数据备份时,其内容仍然是加密过的,但对于证书之类的信息,并没有必要加密,所以会被以明文来存储)。在整个IOS系统中,只有一个全局性的Keychain(OS X中可以用户创建多个Keychain,关于OS X与IOS区别,我们不多考虑),在这个Keychain中,存储了所有IOS 程序的的加密处理过的敏感信息,我们称之为Keychain item,其中每个App程序仅能够访问他自己的Keychain item(不过我们可以通过某种方法在程序间传递Keychain item)。


那么都是什么数据信息可以被存放在Keychain里保护起来呢?在Keychain机制中,通过kSecClass来指明保存的数据信息类型,目前共支持五种信息类型:

kSecClassGenericPassword  used to store a generic password
kSecClassInternetPassword used to store an internet password
kSecClassCertificate      used to store a certificate
kSecClassKey              used to store a kryptographic key
kSecClassIdentity         used to store an identity (certificate + private key)

好了,我们现在有了Keychain是什么的基本概念—— 一个用于存储敏感信息的保险箱,IOS中仅存在一个全局性的Keychain,对于有加密必要的数据,IOS会进行加密,每个IOS程序只能够访问属于他自己的Keychain item。

Keychain item的数据结构

前面所说,Keychain中所存储的条目,被称之为Keychain item,其实是一个字典似得数据结构,即一个key对应一个value,我们操作Keychain中的数据的时候,也是以字典的结构来进行操作的。

Keychain item中存储的数据可以划分为三个区域:

  • 一个表明存储的数据类型,其key前缀为kSecClass*
  • 一组描述数据信息的属性,其key前缀为kSecAttr*
  • 存储敏感数据的内容,其key前缀为kSecValue*



如何操作Keychain

Keychain背后的实现机制虽然很复杂,但对于使用者的我们来说,他只是一个保险箱用来存储敏感数据,我们只需要能够对Keychain进行增删查改的操作即可了,对应的,IOS的Keychain Service API提供如下四个函数

    SecItemCopyMatching  // 查询
    SecItemAdd           // 添加
    SecItemUpdate        // 更新
    SecItemDelete        // 删除


Keychain的实现支持,是使用SQLite数据库的,因此就像SQL语句一样,我需要指明条件来说明我们要进行操作的Keychain item。(通过kSecClass和对应的kSecAttr来指明)

在我们对Keychain item进行操作时,一般的步骤如下:

1、创建一个NSMutableDictionary对象,用于存储或用来设置query条件
2、设置kSecClass,指明我需要获取什么类型数据
3、设置对应的kSecAttr属性,用来指明我需要对哪个Keychain item进行操作。
4、调用IOS中的增删改查函数,传入字典查询条件,并获得对应的结果。(我们当然可以指定我们需要什么返回结果,是BOOL值,还是一组属性或data值)

kSecAttr——唯一标识Keychain item的关键

每个Keychain item都是用了一组属性来唯一的描述,当我们需要对Keychian item进行操作时,也是通过这组属性来定位的。同时,对于重要的要加密的信息,IOS也是通过几个关键属性来对应生成私钥进行加解密的。对于每个class的关键属性,国外的牛人有如下记录:

    For a keychain item of class kSecClassGenericPassword, the primary key is the combination of kSecAttrAccount and kSecAttrService.
    For a keychain item of class kSecClassInternetPassword, the primary key is the combination of kSecAttrAccount, kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol, kSecAttrAuthenticationType, kSecAttrPort and kSecAttrPath.
    For a keychain item of class kSecClassCertificate, the primary key is the combination of kSecAttrCertificateType, kSecAttrIssuer and kSecAttrSerialNumber.
    For a keychain item of class kSecClassKey, the primary key is the combination of kSecAttrApplicationLabel, kSecAttrApplicationTag, kSecAttrKeyType, kSecAttrKeySizeInBits, kSecAttrEffectiveKeySize, and the creator, start date and end date which are not exposed by SecItem yet.
    For a keychain item of class kSecClassIdentity I haven't found info on the primary key fields in the open source files, but as an identity is the combination of a private key and a certificate, I assume the primary key is the combination of the primary key fields for kSecClassKey and kSecClassCertificate.

As each keychain item belongs to a keychain access group, it feels like the keychain access group (field kSecAttrAccessGroup) is an added field to all these primary keys.

参考资料

http://my.oschina.net/w11h22j33/blog/206713

http://stackoverflow.com/questions/11614047/what-makes-a-keychain-item-unique-in-ios

https://www.andyibanez.com/using-ios-keychain/

https://developer.apple.com/library/mac/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html

http://hayageek.com/ios-keychain-tutorial/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值