2013-11-10 59 views
1

自升级到OSX 10.9 Mavericks以来,我一直无法在安全框架中使用Keychain API,因为每次调用Keychain函数时都会抛出未知异常。我已经尝试了许多不同的Keychain包装器实现,当他们调用任何Keychain函数时,它们都会抛出未知的异常。我甚至尝试过在他们的开发人员网站上公布的示例代码,并遇到同样的问题。这是一个已知的问题,如果是这样,修复的状态是什么?他们现在是否有任何方式使用钥匙串?我已经包含了苹果网站下面的示例代码。这里是链接:https://developer.apple.com/library/mac/documentation/Security/Conceptual/keychainServConcepts/03tasks/tasks.html#//apple_ref/doc/uid/TP30000897-CH205-TP9OSX 10.9小牛钥匙串API破碎?

#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); 

} 

回答

0

您的应用程序是否正确地签名?如果不是,许多呼叫将神秘失败。我认为这开始发生在10.8左右。你得到什么错误代码?