Storing a .p12 certificate in keychain to use later

穿精又带淫゛_ 提交于 2019-12-05 21:15:07

I can't think of a good reason to store the certificate in the keychain, although I'm sure there might be some. I store just the identity (which is the private key portion) in the keychain. To make it easier to find the identity in the keychain you generate a persistent reference to it (See listing 2-3 in the link), and then save that persistent reference in the filesystem for your app. The persistent ref is just a CFDataRef, which you can toll free bridge to an NSData object and then easily save/load. When you want the private key for crypto/whatever, you use that persistent reference to load the identity from the keychain (see listing 2-4 in the link). I'd post some code for you but I'm in the process of rebuilding my development machine right now and don't have Xcode installed just yet.

  1. Which am I supposed to store? The certificate or the identity?

It depends on what you are doing, and whether you need the private key on your device for authentication. A SecIdentityRef contains the certificate and private key. If you are using the .p12 file for authentication, then you likely want to store and use the full identity. If you only need the certificate, then I wouldn't be loading the full .p12 onto the drive in the first place, as it contains the private key.

  1. How do I store it and retrieve it?

I would recommend storing your identity (or certificate) in the keychain, and using kSecAttrLabel as a unique reference for querying.

The documentation you need to look at is Storing an Identity in the Keychain, which directs you to Storing a Certificate in the Keychain and outlines some minor differences required between storing an identity and certificate.

This is done as follows (adapted from the links above):

Save to Keychain

// Create a query (with unique label for reference later)
NSDictionary* addquery = @{ (id)kSecValueRef:   (__bridge id)identity,
                            (id)kSecClass:      (id)kSecClassIdentity,
                            (id)kSecAttrLabel:  @"My Identity",
                           };

// Add the identity to the keychain
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)addquery, NULL);
if (status != errSecSuccess) {
    // Handle the error
}

Load from Keychain

// Query the keychain for your identity
NSDictionary *getquery = @{ (id)kSecClass:     (id)kSecClassIdentity,
                            (id)kSecAttrLabel: @"My Identity",
                            (id)kSecReturnRef: @YES,
                            };

// Retrieve the identity from the keychain
SecIdentityRef identity = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)getquery,
                                      (CFTypeRef *)&identity);
if (status != errSecSuccess) { <# Handle error #> }
else                         { <# Use identity #> }

if (identity) { CFRelease(identity); } // After you are done with it

As RyanR mentioned, you can also create a persistent reference to the keychain item once it has been saved, and then save that to file. I would recommend adding [kSecReturnPersistentRef][3] to your addquery to achieve this.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!