我遇到一些麻烦,将从SecKeyRef导出的对称密钥导出到CFDataRef进行包装或存储,或者只是与其他Cocoa代码一起使用。
我有以下代码:
- (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, ¶ms, &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失败(oserr = -25316)
“oserr = -25316”在SecBase.h中定义为:
errSecDataNotAvailable = -25316,/ *无法检索此项目的内容。 * /
我原本以为错误意味着SecKeyRef是早期发布的,或类似的东西,但正如你从日志中看到的那样,SecKey报告自己很好。
关于我在这里遗失或做错的任何想法?谢谢!
答案 0 :(得分:4)
与Apple交谈后,发现此问题是由“Extractable”属性设置为NO引起的,但无法用SecKeyGenerateSymmetric()
已经提交了一个错误,但在解决该错误之前,解决方案是使用折旧方法SecKeyGenerate()
。
而不是上面的- (SecKeyRef)generateRandomSymmetricKey
方法使用此:
- (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;
}
我希望这有助于某人。