Keychain group access to share data between my existing applications
Asked Answered
M

3

24

I have many iOS applications live on AppStore. Now for next version of apps, I want to keep a piece of data for every application to share in KeyChain. As far as I know I need to provide same Keychain access group in Apple's KeychainItemWrapper class.

*keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"Any string" accessGroup:<string representing access group>];

I know about custom URLs and it is of no use as I want data to be persistent.

All my applications have different bundle seed ID as I can see from provisioning portal. I know that the main pre-requisite for shared keychain access is that all of the applications have a common bundle seed ID.

Now my question is how do I make sure that in this senario I can use Keychain to share data among all these applications ?

Is it possible to change the bundle seed ID of all applications through Provisioning profile portal without doing any harm to any functionality ( Although I want to avoid that as there are so many apps).

Is there a way I can add bundle seed ID of all apps in a file and build all apps with that file in project to achieve this ? I know about "keychain-access-groups", do i need to create a plist file and add bundle seed ID of all application in it ?

Appreciate any help in this regard.

Moonshot answered 3/8, 2012 at 9:46 Comment(1)
Is it necessary for the apps to be uploaded to the app store for sharing data through keychain between the apps.How can we check this for our development purpose.Spacetime
S
53

If you have different bundle seed IDs (the ten alphanumeric characters preceding the bundle identifier, the Xs in XXXXXXXXXX.com.company.application), you can't share an access group. It's a restriction on Apple's part and circumventing it is not allowed. I suggest you find another solution of safely sharing data (possibly outside of the device, on a server, but not iCloud as it has the same restrictions).

General information about keychain access groups:

Since iPhone OS 3.0 it has been possible to share data between a family of applications. This can provide a better user experience if you follow the common path of free/premium applications or if you have a set of related applications that need to share some common account settings.

The main pre-requisite for shared keychain access is that all of the applications have a common bundle seed ID. To be clear what this means remember that an App ID consists of two parts:

<Bundle Seed ID> . <Bundle Identifier>

The bundle seed ID is a unique (within the App Store) ten character string that is generated by Apple when you first create an App ID. The bundle identifier is generally set to be a reverse domain name string identifying your app (e.g. com.yourcompany.appName) and is what you specify in the application Info.plist file in Xcode.

So 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.

One caveat, whilst you can create a provisioning profile with a wildcard for the bundle identifier I have never been able to get shared keychain access working between apps using it. It works fine with fully specified (no wildcard) identifiers. Since a number of other Apple services such as push notifications and in-app purchase also have this restriction maybe it should not be a surprise but I am yet to find this documented for keychain access.

Once you have your provisioning profiles setup with a common bundle seed ID the rest is pretty easy. The first thing you need to do is register the keychain access group you want to use. The keychain access group can be named pretty much anything you want as long as it starts with the bundle seed ID. So for example if I have two applications as follows:

ABC1234DEF.com.useyourloaf.amazingApp1

ABC1234DEF.com.useyourloaf.amazingApp2

I could define a common keychain access group as follows:

ABC1234DEF.amazingAppFamily

To enable the application to access this group you need to add an entitlements plist file to the project using xCode. Use Add -> New File and select the Entitlements template from the iPhone OS Code Signing section. You can name the file anything you like (e.g. KeychainAccessGroups.plist). In the file add a new array item named keychain-access-groups and create an item in the array with the value of our chosen keychain access group:

Note: Do not change the get-task-allow item that is created by default in the entitlements file unless you are creating an Ad-Hoc distribution of your app (in which case you should uncheck this option).

This same process should be repeated for all apps that share the bundle seed ID to enable them to access the keychain group. To actually store and retrieve values from this group requires adding an additional value to the dictionary passed as an argument to the keychain services. Using the example from the previous post on simple iPhone keychain access the search dictionary gets the following additional item:

[searchDictionary setObject: @"ABC1234DEF.amazingAppFamily" forKey: (id)kSecAttrAccessGroup];

One final comment, using a shared keychain access group does not stop you from storing values in an applications private keychain as well. The Apple GenericKeychain example application builds two applications which both store data in a private and group keychain.

Source: Use Your Loaf

Slantwise answered 6/8, 2012 at 17:11 Comment(14)
Can you elaborate please. I don't have any entitlement file in my project + all my apps have different seed ids, while I think all apps should have same bundle seed id.Moonshot
@MSK It's quite difficult to explain, so I replaced my explanation by the one from somebody more experienced (I don't use keychains a lot). I hope that helps.Slantwise
I have already read this blog. useyourloaf.com/blog/2010/04/03/keychain-group-access.html My question is because of this statement "The main pre-requisite for shared keychain access is that all of the applications have a common bundle seed ID". All my apps have different bundle seed IDMoonshot
@MSK Are you completely sure your apps have a different bundle seed ID. My 10 apps all have the same. Remember: the bundle seed ID is ten alphanumeric characters generated by Apple. There's only one per developer.Slantwise
I double checked in our provisioning portal, it is different for every app.Moonshot
I don't know whether this is helpful or not to other but this answer helps me that's why +1.Paraffinic
My question was, given that Bundle Seed ids of my apps are different, how can I share information using Keychain ? I am still not convinced that it is NOT possible.Moonshot
@MSK So you aren't convinced Apple likes to put up fences? The whole jailbreak community started to work around those fences. :-pSlantwise
@RandyMarsh So there is no way given by Apple to developers to solve this problem ? Any way I can use shared data in Keychain given that the Bundle Seed ids are different. When I made those apps I had no idea that I should make the Bundle seed ids same because this keychain requirement is pretty new. What I am asking is some valid way of doing it e.g. Can I change Bundle seed ids ? Can I list all those bundle seed ids somewhere in projects's resource etc etcMoonshot
@MSK You can't change them and you can't list them. Anyway, you should contact Apple: they might help you further if they know a solution to their restriction (possibly even change the bundle seed ID for you).Slantwise
@RandyMarsh I would happy to award you the bounty if it is the case. Let me do some more investigation. Anyways Thanks for all your comments.Moonshot
So as par Apple's documentation in my developer provisioning portal here it seems like I am out of luck now.Moonshot
Strange that you have multiple Bundle Seed IDs. Did Apple remove the ability to create a new Bundle Seed ID? When I go to the portal and create a new App ID, it just says Bundle Seed ID (App ID Prefix) - Your Team ID (XXXXXXXXXX) will be used as the App ID Prefix.Familial
Is it necessary for the apps to be uploaded to the app store for sharing data through keychain between the apps.How can we check this for our development purpose.Spacetime
B
7

Now you can use UIPasteboard

//First app, install->run->close->delete
UIPasteboard* board = [UIPasteboard pasteboardWithName:@"com.company.wtv" create:YES];
board.persistent=YES;// persistent to make what you write persist after your app closes, or gets deleted.
[board setValue:@"ccccc" forPasteboardType:@"com.company.wtv.sharedValue"];

//Second app, installed after first one is deleted and ran this one... While bundle identifier and bundle seed different (i tried it on adhoc, not really releasing the app, but i htink the same)
NSData* result=nil;
NSString*resultStr=nil;
result =[board valueForPasteboardType:@"com.company.wtv.sharedValue"];
resultStr=[[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];// I got resultStr containing ccccc

check UIPasteboard documentation for further info. I'll be coming back after using this for my store apps, in case of troubles

Brigand answered 20/12, 2012 at 15:54 Comment(4)
Eventually I already started using pasteboard. Thanks for sharing it here.Moonshot
While this may work for sharing data, it seems quite obviously not secure, so you shouldn't use it for storing passwords or sensitive data.Calmative
yep i used both private and public pasteboards... And to secure myself, i encrypted the data on the public pasteboard... i think i'm going to encrypt the data on the private pasteboard as well in the futureBrigand
The data from paste board is being deleted when we copy anything from the phone in between.how can I resolve it.May be I have to go with custom paste board I think.Is there any sample code for it.Spacetime
A
-1

You can't change your app's bundle ID after it has been put into the AppStore. You also can't make an app read the info from the keychain that was put there by another app (with a different bundle ID). The solution: you'll need an entitlement with which you can access practically all the data.

Aerophagia answered 13/8, 2012 at 6:4 Comment(8)
Can you please elaborate "you'll need an entitlement with which you can access practically all the data."Moonshot
@MSK you'll need to codesign your app using an entitlement which has its keychain-access-group set to *.Aerophagia
Can you please explain the steps to do that. Sorry but I found handling developer account a little scary. I opened my .mobileprovision file in TextEdit and found this <dict> <key>application-identifier</key> <string>T96M553X4T.com.magappzine.airbrushmag</string> <key>aps-environment</key> <string>production</string> <key>get-task-allow</key> <false/> <key>keychain-access-groups</key> <array> <string>T96M553X4T.*</string> </array> </dict>Moonshot
@Moonshot well I've never used the official tools, but for jailbroken/homebrew apps, you can use ldid.Aerophagia
Oh no I am not seeking solution for jailbreak devices, anyways Thanks I wil check and update this question.Moonshot
So it is not possible to share key chain data given that all my apps have different App Ids. So as par Apple's documentation in my developer provisioning portal here it seems like I am out of luck now.Moonshot
@MSK it is possible (AFAIK) but I don't know how to do it on non-jailbroken devices.Aerophagia
let us continue this discussion in chatMoonshot

© 2022 - 2024 — McMap. All rights reserved.