首页 文章

在当前包ID中添加前缀会重置密钥链吗?

提问于
浏览
2

我有一个应用程序(app1),它位于appstore中,包含id为com.x. y 现在我正在使用bundle id com.x在同一个开发者帐户下开发另一个应用程序(app2) . z

我想让app1中存储的app1中的keychain值可用 .

钥匙串的可用性由钥匙串访问组确定 . 所以,如果我将两个前缀(当前团队ID)添加到捆绑ID我能够获取值 . 例如 teamid .com.x.y teamid .com.x.z

Issue is 当我向appstore中的app1添加前缀时,它会再次请求登录凭据,因为应用程序拥有大量用户,所以我不想要这样做 . 我之前没有使用前缀我只是添加了它们 . 有没有办法让我可以获得两个应用程序的钥匙串访问权限,而无需用户再次登录 .

1 回答

  • 1

    首先,它会看到它 . 这是用于对应用程序进行签名的标识符,并且它相信您添加的 teamid 前缀确实可以做任何事情 . 我通常会建议访问组 com.x.sharedcom.x.appgroup.shared 而不使用 com.x.z (我假设 com.x.y 已经存在,所以你不能改变它) .

    我在这里假设你不想强迫用户升级App1,对吗?我正在推进这个假设 .

    如果您可以升级App1(不需要升级,但确保所有新客户都有升级版本),则只存储在 com.x.y (如果存在) . 否则,请存储在 com.x.shared 中:

    • 当您从钥匙串中读取时,请勿使用访问组 . 这将获得第一个匹配记录 .

    • 当您写入钥匙串时,请使用您阅读的记录中的访问组 .

    如果你现在不想升级App1(必需与否),那么只需在App2中读取和写入 com.x.y 即可 .

    当您准备好终止 com.x.y 组(如果您能够最终升级所有App1支持的用户),那么您可以切换到:

    • com.x.y 读取 . 如果已找到,请将其删除,然后将其重新创建为 com.x.shared . 你可以在应用程序启动时一次性执行此操作(只需写一个 NSUserDefaults 表示你已经完成了它 .

    • 从那时起,请始终明确使用 com.x.shared .

    这里的关键工具是当你要求一个显式访问组时,你必须提供整个东西,包括你的AppId(它没有显示在Xcode GUI中) . 您当然可以对其进行硬编码,但更好的解决方案是动态查询它 . 我使用David H's code的更新版本:

    - (NSString *)bundleSeedID {
      NSDictionary *query = @{ (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
                               (__bridge id)kSecAttrAccount : @"bundleSeedIDQuery",
                               (__bridge id)kSecAttrService : @"",
                               (__bridge id)kSecReturnAttributes : (id)kCFBooleanTrue
                               };
      CFDictionaryRef result = nil;
      OSStatus status = SecItemCopyMatching((__bridge CFTypeRef)query,
                                            (CFTypeRef *)&result);
      if (status == errSecItemNotFound)
        status = SecItemAdd((__bridge CFTypeRef)query, (CFTypeRef *)&result);
      if (status != errSecSuccess)
        return nil;
      NSString *accessGroup = [(__bridge NSDictionary *)result
                               objectForKey:(__bridge id)kSecAttrAccessGroup];
      NSArray *components = [accessGroup componentsSeparatedByString:@"."];
      NSString *bundleSeedID = components[0];
      CFRelease(result);
      return bundleSeedID;
    }
    

    这将在运行时告诉您前缀 . 它会这样做b创建一个虚假的钥匙串条目,然后查询它并查看附加到它的访问组 .

    您可能对Renaissance.io 2014的Getting Security and Privacy Right的第一部分感兴趣 . 您可以跳至"Protecting Secrets with Keychain."

相关问题