Cocoa OSX 10.9小牛钥匙链API坏了吗?

Cocoa OSX 10.9小牛钥匙链API坏了吗?,cocoa,keychain,osx-mavericks,security-framework,Cocoa,Keychain,Osx Mavericks,Security Framework,自从升级到OSX 10.9 Mavericks之后,我就无法在安全框架中使用Keychain API,因为每次调用Keychain函数时,它都会抛出一个未知的异常。我尝试过许多不同的Keychain包装器实现,它们在调用任何Keychain函数时都会抛出未知异常。我甚至尝试过苹果在他们的开发者网站上发布的示例代码,但遇到了同样的问题。这是已知问题吗?如果是,修复程序的状态如何?他们现在有没有使用钥匙链的方法?我已经包含了来自苹果网站bellow的示例代码。以下是链接: #包括 #包括 #包括 /

自从升级到OSX 10.9 Mavericks之后,我就无法在安全框架中使用Keychain API,因为每次调用Keychain函数时,它都会抛出一个未知的异常。我尝试过许多不同的Keychain包装器实现,它们在调用任何Keychain函数时都会抛出未知异常。我甚至尝试过苹果在他们的开发者网站上发布的示例代码,但遇到了同样的问题。这是已知问题吗?如果是,修复程序的状态如何?他们现在有没有使用钥匙链的方法?我已经包含了来自苹果网站bellow的示例代码。以下是链接:

#包括
#包括
#包括
//调用SecKeychainAddGenericPassword向密钥链添加新密码:
OSStatus StorePasswordKeychain(无效*密码,UInt32密码长度)
{
骨状态;
状态=SecKeychainAddGenericPassword(
NULL,//默认密钥链
10,//服务名称的长度
“SurfWriter”,//服务名称
10,//帐户名的长度
“MyUserAcct”,//帐户名
passwordLength,//密码的长度
password,//指向密码数据的指针
NULL//项目引用
);
返回(状态);
}
//调用SecKeychainFindGenericPassword从密钥链获取密码:
OSStatus GetPasswordKeychain(无效*密码数据,UInt32*密码长度,
SecKeychainItemRef*itemRef)
{
骨状态1;
status1=SecKeychainFindGenericPassword(
NULL,//默认密钥链
10,//服务名称的长度
“SurfWriter”,//服务名称
10,//帐户名的长度
“MyUserAcct”,//帐户名
passwordLength,//密码的长度
passwordData,//指向密码数据的指针
itemRef//项目引用
);
返回(状态1);
}
//调用SecKeyChainItemModifyAttributes和Data更改的密码
//已在钥匙链中的项目:
OSStatus ChangePasswordKeychain(SecKeychainItemRef itemRef)
{
骨状态;
void*password=“myNewP4sSw0rD”;
UInt32 passwordLength=strlen(密码);
状态=SecKeychainItemModifyAttributesAndData(
itemRef,//项引用
NULL,//属性没有更改
passwordLength,//密码的长度
密码//指向密码数据的指针
);
返回(状态);
}
/* ********************************************************************** */
int main(int argc,const char*argv[]{
骨状态;
骨状态1;
void*myPassword=“myP4sSw0rD”;
UInt32 myPasswordLength=strlen(myPassword);
void*passwordData=nil;//将由
//SecKeychainFindGenericPassword
SecKeychainItemRef itemRef=nil;
UInt32 passwordLength=nil;
status1=GetPasswordKeychain(&passwordData,&passwordLength,&itemRef);//调用
//SecKeychainFindGenericPassword
if(status1==noErr)//如果调用成功,则对用户进行身份验证
//然后继续。
{
//释放SecKeychainFindGenericPassword分配的数据:
状态=SecKeychainItemFreeContent(
NULL,//没有要释放的属性数据
passwordData//释放由分配的数据缓冲区
//SecKeychainFindGenericPassword
);
}
如果(status1==errSecItemNotFound){//密码在密钥链上吗?
/*
若密码不在钥匙链上,则显示对话框以提示用户输入密码
姓名和密码。
对用户进行身份验证。如果失败,请再次提示用户输入名称和密码。
如果成功,询问用户是否在钥匙链上存储新密码;如果否,则返回。
如果是,则存储密码:
*/
status=StorePasswordKeychain(myPassword,myPasswordLength);//调用
//SecKeychainAddGenericPassword
返回(状态);
}
/*
若密码在密钥链上,则验证用户。
如果身份验证成功,则返回。
如果身份验证失败,则提示用户输入新用户名和密码以及
再次验证。
如果不成功,请再次提示。
如果成功,询问是否使用新信息更新密钥链。如果否,返回。
如果是,则存储新信息:
*/
状态=ChangePasswordKeychain(itemRef);//调用
//SecKeychainItemModifyAttributesAndData
if(itemRef)CFRelease(itemRef);
返回(状态);
}

您的应用程序是否正确签名?如果不是这样,许多呼叫将神秘地失败。我想这是在10点8分左右开始的。您得到了什么错误代码

#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
#include <CoreServices/CoreServices.h>

//Call SecKeychainAddGenericPassword to add a new password to the keychain:
OSStatus StorePasswordKeychain (void* password,UInt32 passwordLength)
{
 OSStatus status;
 status = SecKeychainAddGenericPassword (
                NULL,            // default keychain
                10,              // length of service name
                "SurfWriter",    // service name
                10,              // length of account name
                "MyUserAcct",    // account name
                passwordLength,  // length of password
                password,        // pointer to password data
                NULL             // the item reference
    );
    return (status);
 }

//Call SecKeychainFindGenericPassword to get a password from the keychain:
OSStatus GetPasswordKeychain (void *passwordData,UInt32 *passwordLength,
                                                SecKeychainItemRef *itemRef)
{
 OSStatus status1 ;


 status1 = SecKeychainFindGenericPassword (
                 NULL,           // default keychain
                 10,             // length of service name
                 "SurfWriter",   // service name
                 10,             // length of account name
                 "MyUserAcct",   // account name
                 passwordLength,  // length of password
                 passwordData,   // pointer to password data
                 itemRef         // the item reference
    );
     return (status1);
 }

//Call SecKeychainItemModifyAttributesAndData to change the password for
// an item already in the keychain:
OSStatus ChangePasswordKeychain (SecKeychainItemRef itemRef)
{
    OSStatus status;
    void * password = "myNewP4sSw0rD";
    UInt32 passwordLength = strlen(password);

 status = SecKeychainItemModifyAttributesAndData (
                 itemRef,         // the item reference
                 NULL,            // no change to attributes
                 passwordLength,  // length of password
                 password         // pointer to password data
    );
     return (status);
 }


/* ********************************************************************** */

int main (int argc, const char * argv[]) {
    OSStatus status;
    OSStatus status1;

     void * myPassword = "myP4sSw0rD";
     UInt32 myPasswordLength = strlen(myPassword);

     void *passwordData = nil; // will be allocated and filled in by
                               //SecKeychainFindGenericPassword
     SecKeychainItemRef itemRef = nil;
     UInt32 passwordLength = nil;

    status1 = GetPasswordKeychain (&passwordData,&passwordLength,&itemRef);  //Call
                                                //SecKeychainFindGenericPassword
        if (status1 == noErr)       //If call was successful, authenticate user
                                    //and continue.
        {
        //Free the data allocated by SecKeychainFindGenericPassword:
    status = SecKeychainItemFreeContent (
                 NULL,           //No attribute data to release
                 passwordData    //Release data buffer allocated by
                 //SecKeychainFindGenericPassword
    );
 }

    if (status1 == errSecItemNotFound) { //Is password on keychain?
    /*
    If password is not on keychain, display dialog to prompt user for
    name and password.
    Authenticate user.  If unsuccessful, prompt user again for name and password.
    If successful, ask user whether to store new password on keychain; if no, return.
    If yes, store password:
    */
    status = StorePasswordKeychain (myPassword,myPasswordLength); //Call
                                                      // SecKeychainAddGenericPassword
    return (status);
    }

    /*
    If password is on keychain, authenticate user.
    If authentication succeeds, return.
    If authentication fails, prompt user for new user name and password and
     authenticate again.
    If unsuccessful, prompt again.
    If successful, ask whether to update keychain with new information.  If no, return.
    If yes, store new information:
    */
    status = ChangePasswordKeychain (itemRef);  //Call
                                            // SecKeychainItemModifyAttributesAndData
    if (itemRef) CFRelease(itemRef);
    return (status);

 }