iOS:存储在安全区域中的 key 不支持解密

标签 ios objective-c encryption keychain

针对 iOS 11 进行编译(据称它解决了所有与安全飞地相关的错误),我尝试创建存储在安全飞地中的 key 对以用于加密/解密数据,但在该过程中 key 已损坏:

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 检索到的 key 通过 SecKeyCreateEncryptedData 进行加密似乎可行,但是 ...TypeDecrypt 上的 SecKeyIsAlgorithmSupported对于这些 key 返回 false,并尝试解密,不出所料,应用程序崩溃了。

如何/为什么 key 在检索后不起作用?

最佳答案

最后解决的是

  • 将 SecAccessControl 标志更改为 kSecAccessControlBiometryAny|kSecAccessControlPrivateKeyUsage
  • 将 key 类型更改为 kSecAttrKeyTypeECSECPrimeRandom
  • 移动 kSecPrivateKeyAttrs 键下的键属性

不知道为什么苹果会让你搬起石头砸自己的脚,并且不正确验证关键生成参数。

关于iOS:存储在安全区域中的 key 不支持解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66440767/

相关文章:

ios - 启动图像和打开动画是否导致我的应用程序卡住?

c++ - Xcode 4(或 3)iOS,带 C++

ios - 触摸时更改图像

ios - 在 iOS 应用程序中从 MySQL 加载数据

ios - 使用 UIImage 和 UILabels 创建 UICollectionViewCell 会导致滚动缓慢

iphone - MKPolygon 触摸细节 View

encryption - 如何通过 java 的加密扩展加密 PGP 消息?

security - 3 作为 RSA 公共(public)指数有多糟糕

iphone - iOS 上不同的填充类型有什么区别?

objective-c - iOS6 和 UITableView 中的离屏 UITextView