• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - 共享钥匙串(keychain)中的私有(private)数据

[复制链接]
菜鸟教程小白 发表于 2022-12-12 19:17:35 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在为 iOS 钥匙串(keychain)而苦苦挣扎,我似乎找不到任何好的文档。

无论如何,我有两个应用程序,基本上我想做的就是在钥匙串(keychain)中共享一些数据并保持一些数据私有(private),以便其他应用程序无法访问它。

我尝试实现 Apple 提供的 KeychainItemWrapper,但这根本行不通。我没有共享数据的问题,但如果我没有设置访问组,数据仍然是共享的。我使用的设备不是模拟器,这可能会导致同样的问题。

这是我的代码

应用 1:

KeychainItemWrapper *item = [[KeychainItemWrapper alloc] initWithIdentifier"SharedKeyChainApp" accessGroup:nil];
[item setObject"MyAccount" forKey__bridge id)kSecAttrAccount];
[item setObject"SecureValue" forKey__bridge id)kSecValueData];

应用 2:

KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier"SharedKeyChainApp" accessGroup:nil];
NSString *data = [keychain objectForKey__bridge id)kSecValueData];
NSLog(@"data is : %@",data); //Prints "data is : SecureValue"

如果我在一个或另一个应用程序中的项目属性中删除我的钥匙串(keychain)组,它不会打印任何内容。但显然我无法再在这两个应用程序之间共享数据了。

谢谢



Best Answer-推荐答案


如果它是共享的钥匙串(keychain),那么它就是共享的。任何其他可以访问钥匙串(keychain)的应用都可以访问其中的所有数据。

你可以:

  • 创建 2 个钥匙串(keychain)。一个共享一个私有(private)。可共享的东西进入共享状态,私有(private)的东西进入私有(private)状态。
  • 加密您不想与他人共享的数据。

我可能会选择第一个。恕我直言,KeychainItemWrapper 作为抓取和使用代码非常糟糕。这是旧代码,提供的功能很少。我附上了一段我编写的快速而肮脏的代码,用于在没有 KeychainItemWrapper 的情况下使用 key 链功能进行测试和测试。在这种情况下,我正在使用“应用程序”和“安全”中的项目来创建一些共享和非共享项目。你不能在这里说出来,因为它只是一些测试代码,共享在 Targets->Capabilities->Keychain Sharing 下。

- (void)viewDidLoad {
    [super viewDidLoad];

//    [self removeKeychainItem];
//    [self addKeychainItem];
    [self searchForKeychainItems];
}

- (void)searchForKeychainItems {
    [self log"\n\n  EXISTING KEYCHAIN ITEM(S)"];

    NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                            (__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitAll,
                            (__bridge id)kSecReturnData: (__bridge id)kCFBooleanTrue,       // returns password
                            (__bridge id)kSecReturnAttributes: (__bridge id)kCFBooleanTrue, // returns rest of data
//                            (__bridge id)kSecAttrAccessGroup: @"AAAAAAAAAA.com.foo.Security"
//                            (__bridge id)kSecAttrAccessGroup: @"AAAAAAAAAA.com.foo.app"
                        };

    OSStatus resultCode;
    CFArrayRef *searchResults = nil;
    resultCode = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&searchResults);

    NSArray *foo = CFBridgingRelease(searchResults);
    [self log:[NSString stringWithFormat"Search result code: %d", (int)resultCode]];
    [self log:[NSString stringWithFormat"Search Results: %@", foo]];
    NSDictionary *keychainItem = foo[0];
    NSString *password = [[NSString alloc] initWithData:[keychainItem objectForKey__bridge id)kSecValueData] encoding:NSUTF8StringEncoding];
    [self log:[NSString stringWithFormat"password is `%@`", password]];
}

- (void)addKeychainItem {
    [self log"\n\n  ADDING KEYCHAIN ITEM"];

    NSDictionary *genericDataDictionary = @{@"authState": @"1",
                                            @"lastAuthDate": @"2/11/2014",
                                            @"otherCrap": @"poo"};
    NSData *encodedGenericData = [NSKeyedArchiver archivedDataWithRootObject:genericDataDictionary];
    NSData *encodedPassword = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];

    NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                            (__bridge id)kSecAttrCreator: @"MyCom",
                            (__bridge id)kSecAttrComment: @"keychain tests",
                            (__bridge id)kSecAttrService: @"Credentials",
                            (__bridge id)kSecAttrAccount: @"username",
                            (__bridge id)kSecValueData: encodedPassword,
                        (__bridge id)kSecAttrGeneric: encodedGenericData,
                        (__bridge id)kSecAttrAccessGroup: @"AAAAAAAAAA.com.foo.Security"
                        };

    OSStatus result;
    result = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
    NSLog(@"Add status code: %d", (int)result);
}

- (void)removeKeychainItem {
    [self log"\n\n  REMOVING KEYCHAIN ITEM"];

    NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
//                            (__bridge id)kSecAttrCreator: @"MyCom",
//                            (__bridge id)kSecAttrService: @"Credentials",
                            (__bridge id)kSecAttrComment: @"New Keychain standards Test Item",
//                            (__bridge id)kSecAttrAccount: @"username",
//                            (__bridge id)kSecValueData: [@"password" dataUsingEncoding:NSUTF8StringEncoding],
//                            (__bridge id)kSecAttrGeneric: encodedGenericData
                            //                            (__bridge id)kSecAttrAccessGroup: @"AAAAAAAAAA.com.foo.Security"
                            };

    OSStatus resultsCode;
    resultsCode = SecItemDelete((__bridge CFDictionaryRef)query);
    NSLog(@"Delete results code: %d", (int)resultsCode);
}

- (void)logNSString *)text {
    self.textView.text = [[self.textView.text stringByAppendingString:text] stringByAppendingString:@"\n"];
}

关于ios - 共享钥匙串(keychain)中的私有(private)数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21989601/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap