微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

iOS SecKeyRef到NSData

我有两个密钥,公共和私有,都存储在SecKeyRef变量中.为了简单起见,让我们从公众开始.我想做的是将其导出为NSData对象.为此,苹果提供了几个着名的代码片段,它们在这里
- (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,但代码显示错误(“__bridge”在每次转换到id之前被添加).新版本如下所示:

- (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’
>对于指向“CFTypeRef”(也称为“const void *”)的Objective-C指针的间接指针的转换不允许使用ARC

现在,我希望在您的帮助之后,第一个问题将不再是一个问题,因为我不想构建一个查询或什么不能从钥匙串中提取密钥.我有一个变量,我想从中提取它.该变量的名称为givenPublicKey,这是我要转换为NSData的关键字.

那么,我怎么去做这个和解决这个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)];

>对于指向“CFTypeRef”(也称为“const void *”)的Objective-C指针的间接指针的转换不允许使用ARC

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

CFTypeRef result;
sanityCheck = SecItemcopyMatching((__bridge CFDictionaryRef)queryPublicKey,&result);
if (sanityCheck == errSecSuccess) {
    publicKeyBits = CFBridgingrelease(result);
}

>我不想构建一个查询,或者什么不能从钥匙串中提取密钥.我有一个变量,我想从中提取

据我所知,您必须临时将密钥匙存储到钥匙扣. 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,因为我已经读了好几次,我正在尝试使用的功能只适用于公钥.

我不知道.

原文地址:https://www.jb51.cc/iOS/336953.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐