本文主要是介绍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/
这篇关于IOS安全编程之Keychain基本概念的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!