iOS:存储在安全飞地中的密钥不支持解密
iOS: Decryption not supported on key stored in secure enclave
编译 iOS 11(据称解决了所有与安全飞地相关的错误),我正在尝试创建存储在安全飞地中的密钥对以用于 encrypting/decrypting 数据,但是某处密钥被损坏:
CFErrorRef error = NULL;
NSError *gen_error = nil;
SecAccessControlRef sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, kSecAccessControlBiometryAny, &error);
if (sacObject == NULL || error != NULL) { /* handled */ }
NSDictionary *keyAttributes = @{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrKeyType: (id)kSecAttrKeyTypeEC,
(id)kSecAttrKeySizeInBits: @256,
(id)kSecAttrTokenID: (id)kSecAttrTokenIDSecureEnclave,
(id)kSecAttrIsPermanent: @YES,
(id)kSecAttrApplicationTag: biometricKeyTag, //static between all calls
(id)kSecAttrAccessControl: (__bridge_transfer id)sacObject,
};
SecKeyRef privateKey = (__bridge SecKeyRef) CFBridgingRelease(SecKeyCreateRandomKey((__bridge CFDictionaryRef)keyAttributes, (void *)&gen_error));
if (gen_error != nil || privateKey == nil) { /* handled */ }
SecKeyRef publicKey = SecKeyCopyPublicKey(privateKey);
Boolean algorithmDSupported = SecKeyIsAlgorithmSupported(privateKey, kSecKeyOperationTypeDecrypt, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM);
Boolean algorithmESupported = SecKeyIsAlgorithmSupported(publicKey, kSecKeyOperationTypeEncrypt, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM);
// Returns true for both
// OK so far!
// Now retrieve the key just create to mock up using it later
NSDictionary *query = @{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrApplicationTag: biometricKeyTag,
(id)kSecAttrKeyType: (id)kSecAttrKeyTypeEC,
(id)kSecReturnRef: @YES,
(id)kSecUseOperationPrompt: @""
};
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&privateKey);
if (status != noErr || privateKey == NULL) { /* handled */ }
publicKey = SecKeyCopyPublicKey(privateKey);
Boolean algorithmDSupported2 = SecKeyIsAlgorithmSupported(privateKey, kSecKeyOperationTypeDecrypt, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM);
Boolean algorithmESupported2 = SecKeyIsAlgorithmSupported(publicKey, kSecKeyOperationTypeEncrypt, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM);
// Encryption on the public key is supported, but algorithmDSupported2 is false – cannot decrypt with the key any more
使用 SecItemCopyMatching
检索的密钥与 SecKeyCreateEncryptedData
加密似乎可行,但 SecKeyIsAlgorithmSupported
on …TypeDecrypt
returns 这些密钥为 false,并且无论如何尝试解密都会使应用程序崩溃。
How/why取回密钥后是不是失效了?
最后解决的是
- 将 SecAccessControl 标志更改为
kSecAccessControlBiometryAny|kSecAccessControlPrivateKeyUsage
- 正在将密钥类型更改为
kSecAttrKeyTypeECSECPrimeRandom
- 移动
kSecPrivateKeyAttrs
键下的键属性
不知道为什么 Apple 让你搬起石头砸自己的脚,却没有正确验证密钥生成参数。
编译 iOS 11(据称解决了所有与安全飞地相关的错误),我正在尝试创建存储在安全飞地中的密钥对以用于 encrypting/decrypting 数据,但是某处密钥被损坏:
CFErrorRef error = NULL;
NSError *gen_error = nil;
SecAccessControlRef sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, kSecAccessControlBiometryAny, &error);
if (sacObject == NULL || error != NULL) { /* handled */ }
NSDictionary *keyAttributes = @{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrKeyType: (id)kSecAttrKeyTypeEC,
(id)kSecAttrKeySizeInBits: @256,
(id)kSecAttrTokenID: (id)kSecAttrTokenIDSecureEnclave,
(id)kSecAttrIsPermanent: @YES,
(id)kSecAttrApplicationTag: biometricKeyTag, //static between all calls
(id)kSecAttrAccessControl: (__bridge_transfer id)sacObject,
};
SecKeyRef privateKey = (__bridge SecKeyRef) CFBridgingRelease(SecKeyCreateRandomKey((__bridge CFDictionaryRef)keyAttributes, (void *)&gen_error));
if (gen_error != nil || privateKey == nil) { /* handled */ }
SecKeyRef publicKey = SecKeyCopyPublicKey(privateKey);
Boolean algorithmDSupported = SecKeyIsAlgorithmSupported(privateKey, kSecKeyOperationTypeDecrypt, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM);
Boolean algorithmESupported = SecKeyIsAlgorithmSupported(publicKey, kSecKeyOperationTypeEncrypt, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM);
// Returns true for both
// OK so far!
// Now retrieve the key just create to mock up using it later
NSDictionary *query = @{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrApplicationTag: biometricKeyTag,
(id)kSecAttrKeyType: (id)kSecAttrKeyTypeEC,
(id)kSecReturnRef: @YES,
(id)kSecUseOperationPrompt: @""
};
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&privateKey);
if (status != noErr || privateKey == NULL) { /* handled */ }
publicKey = SecKeyCopyPublicKey(privateKey);
Boolean algorithmDSupported2 = SecKeyIsAlgorithmSupported(privateKey, kSecKeyOperationTypeDecrypt, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM);
Boolean algorithmESupported2 = SecKeyIsAlgorithmSupported(publicKey, kSecKeyOperationTypeEncrypt, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM);
// Encryption on the public key is supported, but algorithmDSupported2 is false – cannot decrypt with the key any more
使用 SecItemCopyMatching
检索的密钥与 SecKeyCreateEncryptedData
加密似乎可行,但 SecKeyIsAlgorithmSupported
on …TypeDecrypt
returns 这些密钥为 false,并且无论如何尝试解密都会使应用程序崩溃。
How/why取回密钥后是不是失效了?
最后解决的是
- 将 SecAccessControl 标志更改为
kSecAccessControlBiometryAny|kSecAccessControlPrivateKeyUsage
- 正在将密钥类型更改为
kSecAttrKeyTypeECSECPrimeRandom
- 移动
kSecPrivateKeyAttrs
键下的键属性
不知道为什么 Apple 让你搬起石头砸自己的脚,却没有正确验证密钥生成参数。