使用SecKeychainFindGenericPassword访问KeyChain时偶发的errSecAuthFailed(-25293)?

时间:2009-12-25 15:33:07

标签: cocoa macos keychain

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

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

5 个答案:

答案 0 :(得分:1)

此链接表明您输入的密码不正确。 See Here 有时你有可能只是偶然发送一个空对象作为密码短语吗?

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

答案 1 :(得分: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的内部缓冲区是非连续的,要么不是您要求的编码,或者不兼容。

这样的问题可以在运行时完全像你描述的那样。

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

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

- (BOOL)getCString:(char *)buffer maxLength:(NSUInteger)maxBufferCount encoding:(NSStringEncoding)encoding; 

答案 2 :(得分:0)

我不确定这是不是问题(我不知道它是怎么回事)但我最近改变了我的代码以正确传递cStrings的strlen(),而不是NSString { {1}}进入通话。从技术上讲,这更正确(因为如果涉及UTF-8双字节字符,字符串长度可能与cString不同。

但是,我测试过的用户名/密码都没有包含非ASCII字符,所以我不知道这个问题究竟是如何影响我看到的错误的。我的新代码如下,我没有看到它的错误:

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];
}

答案 3 :(得分:0)

我遇到了同样的问题,在我看来,事实证明这是原因:Cannot access keychain item after SMJobBless update

答案 4 :(得分:0)

发生此问题的一个可能原因是,进行调用的可执行文件无法访问钥匙串项。在Keychain Access中,您可以看到有权访问相关项目的“访问控制”选项卡下的项目的应用程序列表。

如果您的应用从其他位置运行,则会出现此错误。例如,我有一个Privileged Helper Tool,在我的开发机上,我通常以root身份运行Xcode。此可执行文件的路径是Xcode创建它的路径,它是〜/ Library / Developer / Xcode / DerivedData // myexecutable中的路径。当我以用户身份运行它时,它从/ Library / PrivilegedHelperTools / myexecutable运行。因此,如果密码最初是由应用程序的一个版本创建的,并且我尝试使用其他路径读取密码,我将看到errSecAuthFailed错误。

这不是唯一的原因。其他人提到了SMJobBless所具有的升级问题。这也可能导致相同的错误代码,但我确实看到它有两个原因 - 尽管我通过命令帮助工具在升级之前将其自身移动到不同的位置,以编程方式解决了就地升级问题。