有时,当我在Xcode上运行设备上的应用程序时,我会尝试访问密钥链但由于错误-34018而失败.这与任何记录的钥匙串错误代码都不匹配,并且无法一致地再现.(可能有30%的时间发生,我不清楚为什么会发生这种情况).使调试这个问题变得非常困难的原因是完全缺乏文档.知道是什么导致这个以及如何解决它?我正在使用Xcode 5并在设备上运行iOS 7.0.4.
这里有一个公开的问题:https://github.com/soffes/sskeychain/issues/52
编辑:每个请求添加钥匙串访问代码
我正在使用该SSKeychain库与钥匙串连接.这是片段.
#define SERVICE @"default"
@implementation SSKeychain (EXT)
+ (void)setValue:(NSString *)value forKey:(NSString *)key {
NSError *error = nil;
BOOL success = NO;
if (value) {
success = [self setPassword:value forService:SERVICE account:key error:&error];
} else {
success = [self deletePasswordForService:SERVICE account:key error:&error];
}
NSAssert(success, @"Unable to set keychain value %@ for key %@ error %@", value, key, error);
if (!success) {
LogError(@"Unable to set value to keychain %@", error);
}
LogTrace(@"Will set …Run Code Online (Sandbox Code Playgroud) 我正在试图弄清楚如何使用SSkeychain来存储instagram api的访问令牌.我目前正在使用NSUserDefault类,但我不认为这是最好的想法.
SSkeychain类本身是否需要分配和初始化才能使用?
我正在考虑使用SSKeychain在iOS应用程序中存储密码,但我不确定我是否需要一些特定的帐户和服务值,或者它是否可以任意使用.有共同的做法吗?
我一直在使用SSKeychain开源库在我的iOS应用程序中安全地存储数据.昨天,我遇到了一个问题,当我从iTunes将v1.0从v1.0更新到v2.0时,SSKeychain无法保留其数据.
UUID生成代码:
- (NSString *)createNewUUID
{
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return (__bridge NSString *)string;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我生成了一个独特的设备字符串并用于keychain存储相同的设备字符串,并且应用程序在很大程度上依赖于唯一的字符串/设备标识符,因为从iOS5到iOS7 Unique Device Identifier,由于方法已被弃用,因此Apple会进行大量的转换.
适用于Store&Retrive的Cope代码段:
NSString *retrieveuuid = [SSKeychain passwordForService:@"com.name.appname" account:@"AppName"];
if (retrieveuuid == nil) {
NSString *uuid = [self createNewUUID];
//Store the password in Keychain
NSError *error = nil;
[SSKeychain setPassword:uuid forService:@"com.name.appname" account:@"AppName" error:&error];
if ([error code] == SSKeychainErrorNotFound) {
NSLog(@"ID not found");
}
}
Run Code Online (Sandbox Code Playgroud)
因此,当应用程序从Apple更新时,钥匙串将无法保留其值/标识符,或者我在某些时候错过了.请帮助将标识符永久存储在设备中,与安装,卸载,重置和更新应用程序无关.
或者,是否有任何API,它可以在生成时为我提供相同的deviceID /唯一字符串,因此需要存储唯一字符串?
注意: App必须支持iOS 4.3及更高版本.
我有一个iOS应用程序,在Keychain中存储访问令牌.在过去的几个月里,我注意到大约2%的用户在尝试检索令牌时获得了errSecItemNotFound.
所有相关的StackOverflow线程都指向后台任务是罪魁祸首(iOS KeyChain不从后台检索值)或在查询字符串中包含无效参数(Keychain:Item报告为errSecItemNotFound,但在添加时接收errSecDuplicateItem).
我正在使用kSecAttrAccessibleAfterFirstUnlock,因此后台任务应该能够正常访问Keychain.
此外,搜索查询如下所示:
NSMutableDictionary *query = [[NSMutableDictionary alloc] init];
[query setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
[query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
[query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
[query setObject:service forKey:(__bridge id)kSecAttrService];
[query setObject:key forKey:(__bridge id)kSecAttrGeneric];
[query setObject:key forKey:(__bridge id)kSecAttrAccount];
Run Code Online (Sandbox Code Playgroud)
(设置kSecAttrGeneric可能是多余的,但它不会影响查询的结果)
为了记录,我遇到了SSKeyChain和UICKeychainStore的这个错误.
任何提示都将受到高度赞赏:]
我正在使用ios钥匙串(keychainItemWrapper/ SSKeychain)来存储我的应用程序的登录令牌并保持登录状态.目前,我NSDictionary在包含我的令牌,令牌到期和刷新令牌的钥匙串中存储了一个简单的内容.我将它序列化为NSData并使用存储kSecValueData.我还设置了kSecAttrAccount和kSecAttrService,但不使用那些权威性.
这种方法效果很好,大约95%的时间都是如此.问题是随机,不可预测和零星地,当我请求它来检索令牌时,钥匙串不会返回数据.通常在距离应用程序适度的时间之后重新打开它.它不一定是在后台,也不是在任何特定的延迟之后.
询问我当它具体失败NSData的下方,返回<>来代替<ABCD EFGH IJKL ....>.我认为这是零.因此,代码认为用户未登录并立即将其丢弃在我的应用程序的注册/登录登录页面上,没有注销错误,令牌到期错误等.如果我最小化应用程序,然后重新打开,它几乎总是获得正确的钥匙串信息和用户再次登录.
遇到这会产生令人困惑的体验.这也意味着用户无法保持这种真正的100%登录状态,偶尔会被随机注销.我一直无法预测或调试它,更改钥匙串库,如下所示,并没有为我修复它.它适用于我和几个TestFlight用户,以及我们目前的生产应用程序.
有关如何维护钥匙串完整性和加载100%时间的任何建议?我们准备在令牌上实现NSUserDefaults备份存储,以便在这些情况下使用,我真的不想这样做来存储身份验证令牌.
储存:
// load keychain
KeychainItemWrapper *keychainItem = [KeychainItemWrapper keyChainWrapperForKeyID:kcIdentifier];
NSString *firstLaunch = [keychainItem objectForKey: (__bridge id)(kSecAttrAccount)];
if (firstLaunch == nil){
// initialize if needed
[keychainItem setObject:email forKey: (__bridge id)(kSecAttrAccount)];
[keychainItem setObject:kcIdentifier forKey: (__bridge id)kSecAttrService];
[keychainItem setObject:(id)kSecAttrAccessibleAfterFirstUnlock forKey:(id)kSecAttrAccessible];
}
// serialize "auth" NSDictionary into NSData and store
NSString *error;
NSData *dictionaryData = [NSPropertyListSerialization dataFromPropertyList:auth format:NSPropertyListXMLFormat_v1_0 …Run Code Online (Sandbox Code Playgroud) 我正在开发一个iPhone应用程序.
应用程序访问某些Web服务,其他东西应该识别设备ID.
由于不推荐使用UDID,我需要调用CFUUIDCreate来为此生成我自己的UUID.
该ID是安全敏感的:我的所有网络通信都是加密的,我不希望除证书认证服务器之外的任何人都知道UUID.
此外,我希望这个标识符能够在重新安装后继续存在.
使用钥匙串存储该UUID似乎是一个明显的解决方案.
我怎么做?
在互联网上,有一些示例如何在钥匙串中存储用户名和密码.我既没有用户也没有密码,只有16个字节的UUID(或单个NSString).
我需要使用哪个kSecClass?
我需要设置和检索哪些属性?
哪些属性是可选的,哪些属于强制性?
什么标头/框架定义了CSSM_ALGORITHMS?
文档提到cssmtype.h,xcode自动完成有<Security/cssmtype.h>但是xcode编译器说"找不到文件".
从常识来看,"身份"应该最合适.然而,文档说"身份是私钥和证书的组合",我没有.另外,我没有看到"关键字节"属性.
提前致谢!
我正在使用此方法来检索保存的值(并SecItemAdd用于最初添加它):
+ (NSData *)passwordDataForService:(NSString *)service
account:(NSString *)account error:(NSError **)error {
CFTypeRef result = NULL;
NSMutableDictionary *query = [self _queryForService:service account:account];
[query setObject:(__bridge id)kCFBooleanTrue
forKey:(__bridge id)kSecReturnData];
[query setObject:(__bridge id)kSecMatchLimitOne
forKey:(__bridge id)kSecMatchLimit];
status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
if (status != noErr && error != NULL) {
*error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status
userInfo:nil];
return nil;
}
return (__bridge_transfer NSData *)result;
}
Run Code Online (Sandbox Code Playgroud)
这段代码对大多数用户来说运行良好,但我的一小部分用户 (< 1%) 遇到的结果表明这里的读取或写入失败。不幸的是,我的代码吞下了任何错误(即,当它们发生时不会将它们记录在任何地方),所以我不知道为什么它在世界上失败了,而且我根本无法在我的任何开发设备上重现该问题。
有谁知道可以在 iOS 设备上启用的任何可能导致SecItemAdd或SecItemCopyMatching失败的安全/权限设置?我试过打开密码锁定,但这似乎没有效果。
我正在使用SSKeychain实现的新的iCloud Keychain功能.我设置kcQuery.synchronizationMode = SSKeychainQuerySynchronizationMode.Yes了密码
iCloud Keychain现在有用吗?它会与我的其他iDevices同步吗?
我的商品推送到iCloud需要多长时间?
有新方法通知我新密码是否到达我的设备?
谢谢!
我正在使用 SSKeychain 来存储会话令牌。当我从 XCode 编译和运行应用程序时,有时找不到令牌(似乎它偶尔会工作)。但是,如果我拔下设备并在没有 XCode 的情况下运行应用程序,则令牌会返回 10/10 次。我不确定这是否是 SSKeychain 或一般钥匙串的问题。我用来存储和读取值的代码如下:
- (void)setSecureValue:(NSString *)value forKey:(NSString *)key
{
[SSKeychain setPassword:value forService:kServiceName account:key];
}
- (NSString *)secureValueForKey:(NSString *)key
{
if (key != nil)
{
return [SSKeychain passwordForService:kServiceName account:key];
}
return nil;
}
Run Code Online (Sandbox Code Playgroud)
许多围绕钥匙串访问的问题似乎通过意识到钥匙串不是数据存储并且它有时可以被清空(例如由于内存警告)来解决。但是,由于我总是在同一设备上运行,并且在拔下并再次运行后令牌仍然存在,我不知道这可能是这里的问题。
我在哪里可以找到一个很好的详细教程,使用sskeychain来存储和检索用户名和密码,并在UIWebView中进行基本身份验证?其次,就基于Web的应用程序存储和使用身份验证所需的方法而言,我是否在正确的轨道上?(见下面的解释.)
我找到了一些使用不同方法的教程:
根据以下其他SO问题的建议,建议使用sskeychain以便更轻松地使用钥匙串来存储身份验证参数.
我的计划是按照建议在钥匙串中在设备上本地存储用户名和密码,并使用基本身份验证通过UIWebView连接到我的PHP代码.是否有经验丰富的iOS开发人员推荐的有关用户身份验证主题的xcode/Obj-C新手的详细分步教程?
Apple文档似乎不太有用.它既可以是简单的销售术语,也可以是方法和参数的头部描述,没有很多有用的例子.
更新:
我最后只使用NSUserDefaults在本地存储用户名和密码,然后使用AFNetworking库进行身份验证.如果这些是不明智的,我会欢迎一个答案,为更好的方法提供指导.
我发布的应用程序使用CFUUID和SSKeychain来识别设备(即使应用程序已卸载并重新安装,也可以保持该ID不变)
我将这些设备ID保存在服务器中,我最近注意到一些用户为同一个真实设备拥有多个这些ID.我看到的唯一解释是ID没有从Keychain保存或加载,因此设备生成一个新ID.奇怪的是,它在运行相同iOS版本的其他一些设备上运行良好.
关于可能发生什么的任何想法?
这是我的相关代码 (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
NSString* identifier = @"appName";
NSString* serviceName = @"com.company.appName";
NSString *retrieveuuid = [SSKeychain passwordForService:serviceName account:identifier];
if (retrieveuuid == nil) {
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
NSString *uuid = (NSString*) string;
[SSKeychain setPassword:uuid forService:serviceName account:identifier];
}
Run Code Online (Sandbox Code Playgroud)
编辑:我的猜测是retrieveuuid == nil由于某种原因没有按预期工作.稍后在应用程序中我注册了推送通知,并将推送令牌连同我用同一条线读取的CFUUID一起[SSKeychain passwordForService:serviceName account:identifier]发送到服务器但是当它被发送到服务器时它不是零(所以我可以看到几个CFUUID与相同的推送令牌).
编辑2以附加更多实际代码.
AppDelegate.m
NSString* identifier = @"appName";
NSString* serviceName = @"com.company.appName";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Creating UUID …Run Code Online (Sandbox Code Playgroud)