我正在尝试在系统密钥链中保存密码,但它会出现“写入权限错误”,有没有办法以root身份访问它并使用AuthorizationRef或其他任何方式保存密码?
+ (int) createItem:(NSString*)label withService:(NSString*)service account:(NSString*)account description:(NSString*)description andPassword:(NSString*)password {
// This variable will hold all sorts of operation status responses
OSStatus status;
// Converting the NSStrings to char* variables which we will need later
const char *labelUTF8 = [label UTF8String];
const char *serviceUTF8 = [service UTF8String];
const char *accountUTF8 = [account UTF8String];
const char *descriptionUTF8 = [description UTF8String];
const char *passwordUTF8 = [password UTF8String];
// This variable is soon to hold the System Keychain
SecKeychainRef keychain = NULL;
status = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem, &keychain);
if (status == errSecSuccess) {
NSLog(@"Succeeded opening System Keychain");
} else {
NSLog(@"Could not obtain System Keychain: %@", SecCopyErrorMessageString(status, NULL));
return 60;
}
NSLog(@"Unlocking System Keychain");
status = SecKeychainUnlock(keychain, 0, NULL, FALSE);
if (status == errSecSuccess) {
NSLog(@"Succeeded unlocking System Keychain");
} else {
NSLog(@"Could not unlock System Keychain: %@", SecCopyErrorMessageString(status, NULL));
return 61;
}
// This variable is going to hold our new Keychain Item
SecKeychainItemRef item = nil;
SecAccessRef access = nil;
status = SecAccessCreate(CFSTR("Some VPN Test"), (__bridge CFArrayRef)(self.trustedApps), &access);
if(status == noErr) {
NSLog(@"Created empty Keychain access object");
} else {
NSLog(@"Could not unlock System Keychain: %@", SecCopyErrorMessageString(status, NULL));
return 62;
}
// Putting together the configuration options
SecKeychainAttribute attrs[] = {
{kSecLabelItemAttr, (int)strlen(labelUTF8), (char *)labelUTF8},
{kSecAccountItemAttr, (int)strlen(accountUTF8), (char *)accountUTF8},
{kSecServiceItemAttr, (int)strlen(serviceUTF8), (char *)serviceUTF8},
{kSecDescriptionItemAttr, (int)strlen(descriptionUTF8), (char *)descriptionUTF8},
};
SecKeychainAttributeList attributes = {sizeof(attrs) / sizeof(attrs[0]), attrs};
status = SecKeychainItemCreateFromContent(kSecGenericPasswordItemClass, &attributes, (int)strlen(passwordUTF8), passwordUTF8, keychain, access, &item);
NSLog(@"item %@", item);
if(status == noErr) {
NSLog(@"Successfully created Keychain Item");
} else {
NSLog(@"Creating Keychain item failed: %@", SecCopyErrorMessageString(status, NULL));
return 63;
}
return 0;
}
当我向NSTask发出命令并启动它时,我也尝试使用shell脚本,它会产生相同的输出。有没有人知道应该怎么做?
答案 0 :(得分:0)
试试这个:
//first check if item already exists, if it is - it might cause an error while trying to save data
if([self tryToFetchForService:service account:account])
[self deleteItemForService:service account:account];
NSDictionary *query=@{(__bridge id)kSecClass:(__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService:service,
(__bridge id)kSecAttrAccount:account,
(__bridge id)kSecValueData:password,
(__bridge id)kSecAttrLabel:description};
status=SecItemAdd((__bridge CFDictionaryRef)query,NULL);
if(status!=errSecSuccess && error!=NULL)
*error=...; // error initialize
您需要包含安全框架。 如果您需要从钥匙串中删除对象,请参阅下面的
NSDictionary *query=@{(__bridge id)kSecClass:(__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService:service,
(__bridge id)kSecAttrAccount:account,
(__bridge id)kSecReturnRef:@YES};
CFTypeRef result=NULL;
status=SecItemCopyMatching((__bridge CFDictionaryRef)query,&result);
if(status==errSecSuccess)
{
status=SecKeychainItemDelete((SecKeychainItemRef)result);
CFRelease(result); // release core foundation class instance
}
if(status!=errSecSuccess && error!=NULL)
*error=...; // failed operation
答案 1 :(得分:0)
只有管理员帐户才能写入系统密钥链。
使用XPC Helper Services将访问密钥链的代码分解为XPC Helper应用程序,以便帮助程序可以使用root权限运行。