如何在钥匙链中保存 NSString 公钥,然后获取它的 SecKeyRef?
我有一个NSString
,它应该是公钥。我想将它存储在钥匙串中,然后获取它的 SecKeyRef ,以便在其他安全相关函数中使用它,例如 SecKeyEncrypt 等。
为了存储,我使用SecItemAdd
假设我还有公钥的标识符。我尝试获取持久引用,然后通过此获取带有 SecItemCopyMatching 的 SecKeyRef 。我使用以下两个函数。在将密钥字符串传递给 putKey
之前,我将其转换为 NSData
。
-(SecKeyRef)putKey:(NSData *)key withIdentifier:(NSString *)identifier
{
OSStatus status = noErr;
SecKeyRef keyRef = nil;
CFTypeRef persKey = nil;
NSData * identifierTag = [[NSData alloc] initWithBytes:(const void *)[identifier UTF8String] length:[identifier length]];
NSMutableDictionary *queryKey = [[NSMutableDictionary alloc] init];
[queryKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[queryKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
[queryKey setObject:identifierTag forKey:(__bridge id)kSecAttrApplicationTag];
[queryKey setObject:key forKey:(__bridge id)kSecValueData];
[queryKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnPersistentRef];
status = SecItemAdd((__bridge CFDictionaryRef)queryKey, (CFTypeRef *)&persKey);
if (status == errSecDuplicateItem) NSLog(@"Key %@ already exists in the KeyStore, OSStatus = %ld.", identifier, status);
else if (status != noErr) NSLog(@"Error putting key %@ in KeyStore, OSStatus = %ld.", identifier, status);
keyRef = [self getKeyRefWithPersistentKeyRef:persKey];
return keyRef;
}
- (SecKeyRef)getKeyRefWithPersistentKeyRef:(CFTypeRef)persistentRef
{
OSStatus sanityCheck = noErr;
SecKeyRef keyRef = NULL;
if (persistentRef == NULL) NSLog(@"persistentRef object cannot be NULL.");
NSMutableDictionary * queryKey = [[NSMutableDictionary alloc] init];
// Set the SecKeyRef query dictionary.
[queryKey setObject:(__bridge id)persistentRef forKey:(__bridge id)kSecValuePersistentRef];
[queryKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
// Get the key reference.
sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)queryKey, (CFTypeRef *)&keyRef);
return keyRef;
}
SecItemAdd
成功返回持久密钥引用。
SecItemCopyMatching
returns 0x0. Anyone knows why?I have a NSString
which is supposed to be a public key. I want to store it in the keychain and then get a SecKeyRef
of it, in order to use it in other security related functions like SecKeyEncrypt
, etc.
For storing I use the SecItemAdd
supposing that I also have an identifier for the public key. I tried to get a persistent ref and then with this get a SecKeyRef
with SecItemCopyMatching
. I use the below two functions. Before I pass the string of key to putKey
I converted it to NSData
.
-(SecKeyRef)putKey:(NSData *)key withIdentifier:(NSString *)identifier
{
OSStatus status = noErr;
SecKeyRef keyRef = nil;
CFTypeRef persKey = nil;
NSData * identifierTag = [[NSData alloc] initWithBytes:(const void *)[identifier UTF8String] length:[identifier length]];
NSMutableDictionary *queryKey = [[NSMutableDictionary alloc] init];
[queryKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[queryKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
[queryKey setObject:identifierTag forKey:(__bridge id)kSecAttrApplicationTag];
[queryKey setObject:key forKey:(__bridge id)kSecValueData];
[queryKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnPersistentRef];
status = SecItemAdd((__bridge CFDictionaryRef)queryKey, (CFTypeRef *)&persKey);
if (status == errSecDuplicateItem) NSLog(@"Key %@ already exists in the KeyStore, OSStatus = %ld.", identifier, status);
else if (status != noErr) NSLog(@"Error putting key %@ in KeyStore, OSStatus = %ld.", identifier, status);
keyRef = [self getKeyRefWithPersistentKeyRef:persKey];
return keyRef;
}
- (SecKeyRef)getKeyRefWithPersistentKeyRef:(CFTypeRef)persistentRef
{
OSStatus sanityCheck = noErr;
SecKeyRef keyRef = NULL;
if (persistentRef == NULL) NSLog(@"persistentRef object cannot be NULL.");
NSMutableDictionary * queryKey = [[NSMutableDictionary alloc] init];
// Set the SecKeyRef query dictionary.
[queryKey setObject:(__bridge id)persistentRef forKey:(__bridge id)kSecValuePersistentRef];
[queryKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
// Get the key reference.
sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)queryKey, (CFTypeRef *)&keyRef);
return keyRef;
}
The SecItemAdd
returns successfully a persistent key ref.
But SecItemCopyMatching
returns 0x0. Anyone knows why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
查看 Apple 的加密练习。为了将公钥添加到 KeyChain,需要去掉附加的标头。 Apple 的示例表明就是这样做的,并且代码很容易重用。
Checkout Apple's Crypto Exercise. In order to add a public key to the KeyChain, it is necessary to strip off the header that is attached to it. Apple's example shows doing just that, and the code is easy to reuse.