首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将对称密钥SecKeyRef项导出为CFDataRef

将对称密钥SecKeyRef项导出为CFDataRef
EN

Stack Overflow用户
提问于 2011-09-15 05:59:37
回答 1查看 2.6K关注 0票数 2

在将对称密钥从SecKeyRef导出到CFDataRef以进行包装或存储,或者简单地用于其他Cocoa代码时,我遇到了一些问题。

我有以下代码:

代码语言:javascript
复制
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    SecKeyRef sessionKey = [self generateRandomSymmetricKey];
    CFDataRef sessionKeyData = [self exportSymmetricKeyAsCFData:sessionKey];
}

- (SecKeyRef)generateRandomSymmetricKey {
    SecKeyRef cryptoKey = NULL;
    CFErrorRef error = NULL;

    // Create the dictionary of key parameters
    CFMutableDictionaryRef parameters = (__bridge CFMutableDictionaryRef)[NSMutableDictionary dictionaryWithObjectsAndKeys:kSecAttrKeyTypeAES, kSecAttrKeyType, (__bridge CFNumberRef)[NSNumber numberWithInt:256], kSecAttrKeySizeInBits, nil];

    // Generate a symmetric key based on the parameters
    cryptoKey = SecKeyGenerateSymmetric(parameters, &error);

    return cryptoKey;
}

- (CFDataRef)exportSymmetricKeyAsCFData:(SecKeyRef)cryptoKey {  
    // Create and populate the parameters object with a basic set of values
    SecItemImportExportKeyParameters params;

    params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
    params.flags = 0;
    params.passphrase = NULL;
    params.alertTitle = NULL;
    params.alertPrompt = NULL;
    params.accessRef = NULL;
    // These two values are for import
    params.keyUsage = NULL;
    params.keyAttributes = NULL;

    // Create and populate the key usage array
    CFMutableArrayRef keyUsage = (__bridge CFMutableArrayRef)[NSMutableArray arrayWithObjects:kSecAttrCanEncrypt, kSecAttrCanDecrypt, nil];

    // Create and populate the key attributes array
    CFMutableArrayRef keyAttributes = (__bridge CFMutableArrayRef)[NSMutableArray array];

    // Set the keyUsage and keyAttributes in the params object
    params.keyUsage = keyUsage;
    params.keyAttributes = keyAttributes;

    // Set the external format and flag values appropriately
    SecExternalFormat externalFormat = kSecFormatUnknown; // Should result in the default appropriate external format for the given key.
    int flags = 0;

    // Export the CFData Key
    CFDataRef keyData = NULL;
    CFShow(cryptoKey);
    OSStatus oserr = SecItemExport(cryptoKey, externalFormat, flags, &params, &keyData);
    if (oserr) {
        fprintf(stderr, "SecItemExport failed (oserr= %d)\n", oserr);
        exit(-1);
    }

    NSLog(@"Exported Symmetric Key Data: %@", [(__bridge NSData *)keyData bytes]);
    return keyData;
}

但我最后在日志里看到的是:

SecItemExport failed (oserr= -25316)

"oserr= -25316“在SecBase.h中定义为:

errSecDataNotAvailable = -25316,无法检索此项的内容。*/

我本来以为这个错误意味着SecKeyRef提前发布了或者类似的东西,但是正如您从日志中可以看到的那样,SecKey正在报告自己的情况。

对我错过了什么或者做错了什么有什么想法吗?谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-10-07 17:15:29

与苹果交谈后,发现这个问题是由“可提取”属性设置为NO造成的,但无法使用SecKeyGenerateSymmetric()设置该参数。

一个bug已经被归档,但是在这个bug被解决之前,解决方案是使用折旧的方法SecKeyGenerate()

与上面的- (SecKeyRef)generateRandomSymmetricKey方法不同,请使用以下方法:

代码语言:javascript
复制
- (SecKeyRef)generateRandomSymmetricKey {
    SecKeyRef symmetricKey;

    OSStatus oserr = SecKeyGenerate(NULL, CSSM_ALGID_AES, 256, 0, (CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_ENCRYPT), CSSM_KEYATTR_EXTRACTABLE, NULL, &symmetricKey);
    if (oserr) {
        NSLog(@"SecKeyGenerate failed: %@", (__bridge NSString *)SecCopyErrorMessageString(oserr, NULL));
        exit(-1);
    }

    return symmetricKey;
}

我希望这能帮上忙。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7426464

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档