2014-03-04 48 views
2

我想将对称密钥存储在OS X的钥匙串中。我通过Apple DevDocs读取了我应该使用SecItemAdd来完成此操作。我也读了CryptoExercise,没有为我提供任何解决方案。
但是当我这样做时,我总是得到OSStatus

errSecNoSuchAttr (-25303)

如何使用“SecItemAdd”在OS X中存储对称密钥?

Codesnippet如下:

//Labels and app tags 
NSString *label = @"My Testkey"; 
NSData * peerTag = [[NSData alloc] initWithBytes:(const void *)[label UTF8String] length:[label length]]; 

// Generating testkey 
NSMutableData *key = [NSMutableData dataWithLength:kCCKeySizeAES128]; 
SecRandomCopyBytes(kSecRandomDefault, kCCKeySizeAES128, [key mutableBytes]); 

// Setting dictionary for adding to keychain 
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
[dict setObject:(id)kSecClassKey forKey:(id)kSecClass]; 
[dict setObject:(id)kSecAttrKeyTypeAES forKey:(id)kSecAttrKeyType]; 
[dict setObject:kSecAttrKeyClassSymmetric forKey:(id)kSecAttrKeyClass]; 
[dict setObject:peerTag forKey:(id)kSecAttrApplicationTag]; 
[dict setObject:[NSNumber numberWithUnsignedInteger:kCCKeySizeAES128] forKey:(id)kSecAttrKeySizeInBits]; 
[dict setObject:key forKey:(id)kSecValueData]; 

// Adding to keychain 
OSStatus osstatus = SecItemAdd((__bridge CFDictionaryRef)dict, NULL); 

//Just give me a result (in this case a label in the app) 
[[self statusField] setStringValue:[NSString stringWithFormat:@"Key: %@\nStatus: %@", [key base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength], SecCopyErrorMessageString(osstatus, NULL)]]; 

我做错了吗?任何帮助将不胜感激。谢谢。

回答

2

我在做什么错了?任何帮助将不胜感激。

看起来不支持kSecAttrKeyClassSymmetric。从谷歌搜索的苹果源代码(SecAttrKeyClassSymmetric site:opensource.apple.com),它看起来像你从SecKey.c一个NULL:

case 2: // kSecAttrKeyClassSymmetric 
    secwarning("Unsupported symmetric key type: %@", ktype); 
    ref = NULL; 
    break; 
... 

基地编码,并使用kSecClassGenericPassword。或者,尝试在没有编码的情况下将其塞入钥匙串中。数组是一个数组。

请记住,我可能会读错那些来源。我没有阅读很多苹果的源代码(我试图避免苹果)。

+0

经过深入挖掘,我发现,你是对的。我喜欢苹果,但似乎结果是,KeyChain API没有得到CommonCrypto API的全面支持。非常感谢您的建议。 对其他可能存在问题的人来说很清楚: CC API与OS X的KeyChain API有点不兼容,这反过来又与iOS的API不兼容。 您必须使用Keychain API,并且如果您有自己的密钥(例如由CommomCrypto创建),则必须使用KeyChain API方法导入它。你不能直接存储。 – Eurobertics