kSecAttrTokenIDSecureEnclave 记录在哪里?

Where is kSecAttrTokenIDSecureEnclave documented?

我正在努力尝试使用 kSecAttrTokenIDSecureEnclave 生成私钥-public 密钥对,以便在安全飞地中生成私钥。

kSecAttrTokenIDSecureEnclave 记录在哪里?下面是我的代码,它失败了,状态代码为 -50。

- (void)generateKeyPair {
    const UInt8 publicTagString[] = "public";
    const UInt8 privateTagString[] = "private";

    publicTag = CFDataCreate(0, publicTagString, sizeof(publicTagString));
    privateTag = CFDataCreate(0, privateTagString, sizeof(privateTagString));

    CFMutableDictionaryRef publicAttr = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
    CFDictionaryAddValue(publicAttr, kSecAttrApplicationTag, publicTag);
    // CFDictionaryAddValue(publicAttr, kSecAttrIsPermanent, kCFBooleanTrue);
    CFDictionaryAddValue(publicAttr, kSecAttrCanEncrypt, kCFBooleanFalse);
    CFDictionaryAddValue(publicAttr, kSecAttrCanDecrypt, kCFBooleanFalse);
    CFDictionaryAddValue(publicAttr, kSecAttrCanDerive, kCFBooleanFalse);
    CFDictionaryAddValue(publicAttr, kSecAttrCanSign, kCFBooleanFalse);
    CFDictionaryAddValue(publicAttr, kSecAttrCanVerify, kCFBooleanTrue);
    CFDictionaryAddValue(publicAttr, kSecAttrCanUnwrap, kCFBooleanFalse);

    CFMutableDictionaryRef privateAttr = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
    CFDictionaryAddValue(privateAttr, kSecAttrApplicationTag, privateTag);
    // CFDictionaryAddValue(privateAttr, kSecAttrIsPermanent, kCFBooleanTrue);
    CFDictionaryAddValue(privateAttr, kSecAttrCanEncrypt, kCFBooleanFalse);
    CFDictionaryAddValue(privateAttr, kSecAttrCanDecrypt, kCFBooleanFalse);
    CFDictionaryAddValue(privateAttr, kSecAttrCanDerive, kCFBooleanFalse);
    CFDictionaryAddValue(privateAttr, kSecAttrCanSign, kCFBooleanTrue);
    CFDictionaryAddValue(privateAttr, kSecAttrCanVerify, kCFBooleanFalse);
    CFDictionaryAddValue(privateAttr, kSecAttrCanUnwrap, kCFBooleanFalse);

    const void* parameterKeys[] = {
        kSecAttrKeyType,
        kSecAttrKeySizeInBits,
        kSecAttrTokenID,
        kSecPublicKeyAttrs,
        kSecPrivateKeyAttrs
    };

    int intKeySize = 512;
    CFNumberRef keySize = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &intKeySize);

    const void* parameterValues[] = {
        kSecAttrKeyTypeRSA,
        keySize,
        kSecAttrTokenIDSecureEnclave,
        publicAttr,
        privateAttr
    };

    CFDictionaryRef parameters = CFDictionaryCreate(
        kCFAllocatorDefault,
        parameterKeys,
        parameterValues,
        5, // ??? Make this programmatic
        NULL,
        NULL
    );

    OSStatus status = SecKeyGeneratePair(parameters, &publicKey, &privateKey);

    if(status != errSecSuccess) {
        [self logError:[NSString stringWithFormat:@"SecKeyGeneratePair status %d", (int)status] :nil];
        return;
    }
}

您收到的错误 -50 表示参数错误。您传递给函数的参数不正确或不适合操作。如果您查看 SecItem header 或您将看到:

kSecAttrTokenIDSecureEnclave Specifies well-known identifier of the token implemented using device's Secure Enclave. The only keychain items supported by the Secure Enclave token are 256-bit elliptic curve keys (kSecAttrKeyTypeEC). Keys must be generated on the secure enclave using SecKeyGenerateKeyPair call with kSecAttrTokenID set to kSecAttrTokenIDSecureEnclave in the parameters dictionary, it is not possible to import pregenerated keys to kSecAttrTokenIDSecureEnclave token.

在安全区域中生成私钥时,RSA 目前不是受支持的密码。切换到 256 位 EC 密钥。

WWDC 2015 session 706 Security And Your Apps 对此进行了介绍。 Apple 示例项目 "KeychainTouchID" 显示了使用安全飞地生成和使用密钥的正确参数。