2

我正在编写一个将密码存储在钥匙串上的应用程序,然后使用 SecKeychainFindGenericPassword() 获取它们。这在 90% 的时间里都有效,但每隔一段时间,对 SecKeychainFindGenericPassword() 的调用就会失败,并显示 errSecAuthFailed (-25293)。当它发生时,只需再试一次,或重新启动应用程序即可修复它。

有谁知道是什么原因造成的?对此错误的一般 Google 搜索指向钥匙串损坏或钥匙串被锁定 - 这两种情况都不是这里的情况,因为后续调用再次成功......

4

5 回答 5

1

此链接表明您输入的密码不正确。请参阅此处 是否有可能有时您只是偶然发送一个空对象作为密码?

或者,您可以尝试EMKeychain。我在 GitHub 上有一个更新的版本:http: //github.com/ctshryock/EMKeychain

于 2009-12-26T01:25:54.530 回答
1

你没有分享你的问题的代码,所以我猜你的问题不是钥匙串功能失调,而是一些编码错误。

这是一个常见的陷阱:由于 KeyChain API 是“C”,并且它们只接受 C 样式的空终止字符串缓冲区,因此您通常需要将 CFString/NSString 对象转换为 C 缓冲区,然后再将它们交给 API。

许多使用的东西,如:

const char *usernameCStr = [username UTF8String];

对于 NSString 或其 CFString 伴侣...

const char *CFStringGetCStringPtr(CFStringRef theString, CFStringEncoding encoding);        /* May return NULL at any time; be prepared for NULL */

忽略这些 API 可能返回 NULL 的事实。要么是因为 CF/NSString 的内部缓冲区不连续,要么不是您要求的编码,或者不是 c 兼容的。

此类问题在运行时的行为可能与您所描述的完全一样。

在这种情况下,您应该发现问题并使用不同的 API 将 CF/NS 字符串复制到 C 缓冲区中:

Boolean CFStringGetCString(CFStringRef theString, char *buffer, CFIndex bufferSize, CFStringEncoding encoding);

或者

- (BOOL)getCString:(char *)buffer maxLength:(NSUInteger)maxBufferCount encoding:(NSStringEncoding)encoding; 
于 2016-09-01T12:50:11.627 回答
0

One possible reason that this issue can occur is if the executable making the call does not have access to the keychain item. In Keychain Access you can see a list of the apps that have permission to access the item under the Access Control tab for the item in question.

If your app is running from a different location, you will get this error. For example, I have a Privileged Helper Tool that on my dev machine I typically run through Xcode as root. The path to this executable is the path at which Xcode creates it which is a path in ~/Library/Developer/Xcode/DerivedData//myexecutable. When I run it as a user would, it is being run from /Library/PrivilegedHelperTools/myexecutable. So if the password was initially created by one version of the app and I try to read it using the other path, I will see the errSecAuthFailed error.

This isn't the only reason. Someone else mentioned the upgrade in place problem that SMJobBless has. That can also result in the same error code, but for sure I see it for both reasons - although I programmatically solved the upgrade in place issue by ordering the helper tool to move itself to a different location before I do the upgrade.

于 2014-03-20T21:12:03.840 回答
0

I'm not sure this was the problem (i don't see how it could have been) but i recently changed my code to properly pass the strlen() of the cStrings, rather then the length of the NSStrings into the call. Technically this is more correct (since the string length might differ from the cString, if UTF-8 dual-byte characters are involved.

BUT, none of the usernames/passwords i tested with contained non-ASCII characters, so i don;t see how this problem could have actually affected the errors I was seeing. My new code is as follows, and i have not seen the error with it:

UInt32 length;
void *data;
const char *account = [[BC_HOST stringByAppendingFormat:@":%@", login] cStringUsingEncoding:NSUTF8StringEncoding];
NSLog(@"Getting password from keychain.");
OSStatus s = SecKeychainFindGenericPassword (nil, 
                     strlen(BC_APPNAME), BC_APPNAME, 
                     strlen(account), account,
                     &length, &data, &keychainItem);
if (s != 0) NSLog(@"Error %d obtaining password from keychain.", s);
if (s == 0)
{
    password = [[NSString alloc] initWithBytes:data length:length encoding:NSUTF8StringEncoding];
}
于 2011-02-02T10:04:26.013 回答
0

我遇到了同样的问题,在我的情况下,这被证明是原因:在 SMJobBless 更新后无法访问钥匙串项目

于 2013-08-15T14:24:16.877 回答