将对称密钥 SecKeyRef 项导出为 CFDataRef
我在将对称密钥从 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 报告本身很好。
关于我在这里缺少什么或做错了什么有什么想法吗?谢谢!
I am having some trouble with getting a symmetric key exported from a SecKeyRef to a CFDataRef for wrapping or storing,or simply for use with other Cocoa code.
I have the following code:
- (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;
}
But all I end up with in my logs is:
SecItemExport failed (oserr= -25316)
"oserr= -25316" is defined in SecBase.h as:
errSecDataNotAvailable = -25316, /* The contents of this item cannot be retrieved. */
I would have originally thought that error to mean that the SecKeyRef was released early or something like that, but as you can see from the log, the SecKey is reporting itself just fine.
Any ideas as to what I'm missing or doing wrong here? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
与 Apple 交谈后,发现此问题是由“Extractable”属性设置为 NO 引起的,但无法使用 SecKeyGenerateSymmetric() 设置该参数。
已提交错误,但本质上是在该错误得到解决之前,解决方案是使用已弃用的方法
SecKeyGenerate()
。而不是上面的
- (SecKeyRef)generateRandomSymmetricKey
方法,请使用以下方法:我希望这对某人有帮助。
After talking with Apple, it turns out this issue is caused by the "Extractable" attribute being set to NO, but having no way to set that parameter with
SecKeyGenerateSymmetric()
A bug has been filed, but essentially until that bug is resolved the solution is to use the depreciated method
SecKeyGenerate()
.Instead of the
- (SecKeyRef)generateRandomSymmetricKey
method above use this:I hope this helps someone.