ari*_*rik 16 rsa objective-c ios
我有两个密钥,public和private,都存储在SecKeyRef变量中.为简单起见,让我们从公众开始吧.我想做的是将它导出到NSData对象.为此,Apple提供了一个几乎着名的代码片段,它位于:
- (NSData *)getPublicKeyBits {
OSStatus sanityCheck = noErr;
NSData * publicKeyBits = nil;
NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init];
// Set the public key query dictionary.
[queryPublicKey setObject:(id)kSecClassKey forKey:(id)kSecClass];
[queryPublicKey setObject:publicTag forKey:(id)kSecAttrApplicationTag];
[queryPublicKey setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnData];
// Get the key bits.
sanityCheck = SecItemCopyMatching((CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKeyBits);
if (sanityCheck != noErr)
{
publicKeyBits = nil;
}
[queryPublicKey release];
return publicKeyBits;
}
Run Code Online (Sandbox Code Playgroud)
但是,我有Xcode 4.6.2,并且代码显示错误(在每次转换为id之前添加"__bridge").新版本看起来像这样:
- (NSData *)getPublicKeyBitsFromKey:(SecKeyRef)givenKey {
OSStatus sanityCheck = noErr;
NSData * publicKeyBits = nil;
NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init];
// Set the public key query dictionary.
[queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag];
[queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
[queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnData];
// Get the key bits.
sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKeyBits);
if (sanityCheck != noErr)
{
publicKeyBits = nil;
}
return publicKeyBits;
}
Run Code Online (Sandbox Code Playgroud)
但仍有两个错误:
现在,我希望在你的帮助之后,第一个问题将不再是一个问题,因为我不想构建一个查询或什么来从密钥链中提取密钥.我把它放在变量中,我希望从那里提取它.变量的名称是givenPublicKey
,这是我希望转换为NSData的密钥.
那么,我将如何做到这一点并解决这个ARC问题呢?
后续:如何将私钥导出到NSData,因为我已经多次读过我正在尝试使用的函数仅适用于公钥.
Mar*_*n R 15
这publicTag
只是添加到Keychain项目中的一些唯一标识符.在CryptoExercise示例项目中,它被定义为
#define kPublicKeyTag "com.apple.sample.publickey"
static const uint8_t publicKeyIdentifier[] = kPublicKeyTag;
NSData *publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];
Run Code Online (Sandbox Code Playgroud)
这可以通过使用临时CFTypeRef
变量来解决:
CFTypeRef result;
sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)queryPublicKey, &result);
if (sanityCheck == errSecSuccess) {
publicKeyBits = CFBridgingRelease(result);
}
Run Code Online (Sandbox Code Playgroud)
据我所知,你必须暂时将SecKeyRef存储到Keychain.SecItemAdd
可以选择将添加的项目作为数据返回.从文档:
要获取作为类型对象的添加项的数据
CFDataRef
,请指定kSecReturnData
值为 的返回类型键kCFBooleanTrue
.
把所有这些放在一起,下面的代码应该做你想要的:
- (NSData *)getPublicKeyBitsFromKey:(SecKeyRef)givenKey {
static const uint8_t publicKeyIdentifier[] = "com.your.company.publickey";
NSData *publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];
OSStatus sanityCheck = noErr;
NSData * publicKeyBits = nil;
NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init];
[queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag];
[queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
// Temporarily add key to the Keychain, return as data:
NSMutableDictionary * attributes = [queryPublicKey mutableCopy];
[attributes setObject:(__bridge id)givenKey forKey:(__bridge id)kSecValueRef];
[attributes setObject:@YES forKey:(__bridge id)kSecReturnData];
CFTypeRef result;
sanityCheck = SecItemAdd((__bridge CFDictionaryRef) attributes, &result);
if (sanityCheck == errSecSuccess) {
publicKeyBits = CFBridgingRelease(result);
// Remove from Keychain again:
(void)SecItemDelete((__bridge CFDictionaryRef) queryPublicKey);
}
return publicKeyBits;
}
Run Code Online (Sandbox Code Playgroud)
我希望这个有效,我现在无法测试它.
我不知道.
归档时间: |
|
查看次数: |
12131 次 |
最近记录: |