gpt4 book ai didi

iOS SecKeyRef 到 NSData

转载 作者:IT王子 更新时间:2023-10-29 08:19:59 28 4
gpt4 key购买 nike

我有两个 key ,公钥和私钥,都存储在 SecKeyRef 变量中。为了简单起见,让我们从公共(public)的开始。我想做的是将它导出到一个 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;
}

但是,我有 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;
}

不过还是有两个错误:

  • 使用未声明的标识符“publicTag”
  • ARC 不允许强制转换指向“CFTypeRef ”(又名“const void *”)的 Objective-C 指针

现在,我希望在你的帮助下,第一个问题将不再是问题,因为我不想构建查询或诸如此类的东西来从钥匙串(keychain)中提取 key 。 我把它放在一个变量中,我希望从那里提取它。变量的名称是 givenPublicKey,这是我希望转换为 NSData 的 key 。

那么,我将如何着手解决这个 ARC 问题?

跟进:我怎样才能将一个私钥导出到 NSData,因为我多次读到我尝试使用的函数只适用于公钥。

最佳答案

  • 使用未声明的标识符“publicTag”

publicTag 只是添加到钥匙串(keychain)项目的一些唯一标识符。在 CryptoExercise 示例项目中,它被定义为

#define kPublicKeyTag "com.apple.sample.publickey"
static const uint8_t publicKeyIdentifier[] = kPublicKeyTag;
NSData *publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];
  • ARC 不允许转换指向“CFTypeRef”(又名“const void *”)的 Objective-C 指针的间接指针

这可以通过使用临时的 CFTypeRef 变量来解决:

CFTypeRef result;
sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)queryPublicKey, &result);
if (sanityCheck == errSecSuccess) {
publicKeyBits = CFBridgingRelease(result);
}
  • 我不想构建查询或诸如此类的东西来从钥匙串(keychain)中提取 key 。我把它放在一个变量中,我希望从那里提取它 ...

据我所知,你必须暂时将SecKeyRef存储到Keychain中。 SecItemAdd可以选择将添加的项目作为数据返回。来自文档:

To obtain the data of the added item as an object of type CFDataRef, specify the return type key kSecReturnData with a value of 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;
}

我希望这能奏效,我现在无法测试它。

  • 跟进:我如何将私钥导出到 NSData,因为我读过好几次,我尝试使用的函数仅适用于公钥。

我不知道。

关于iOS SecKeyRef 到 NSData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16748993/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com