Secure Enclave Key Persistence When Passcode is Removed

I am using the Secure Enclave to generate private keys with kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly and SecAccessControlCreateFlags.biometryCurrentSet. The public key is derived from the Secure Enclave private key at creation and stored in the Keychain for later retrieval.

During testing, I observed the following:

  1. When the device's passcode is removed, the public key stored in the Keychain is deleted as expected.

  2. However, the private key in the Secure Enclave can still be fetched using SecItemCopyMatching, despite being tied to the passcode for protection.

My questions are:

  • Is this behavior expected?

  • How does the Secure Enclave manage private keys in scenarios where the passcode is removed?

  • Is there a way to ensure that the Secure Enclave private key is deleted entirely (not just rendered inaccessible) when the passcode is removed?

Any clarification or relevant documentation references would be very helpful. Thank you!

Is this behavior expected?

Not by you, obviously (-:

Actually, the behaviour you’re seeing is quite weird. I suspect that enabling biometric control is actually preventing WhenPasscodeSet being effective.

Try this:

  1. Create the key pair as you’ve described.

  2. Before removing the device passcode, call SecItemCopyMatching to get both items.

  3. Then print the value of the kSecAttrAccessControl.

What do you see?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi Quinn,

I followed your suggestion to print the kSecAttrAccessControl values before removing the device passcode. Here are the results:

Before removing the passcode:

  • Private key kSecAttrAccessControl:

    <SecAccessControlRef: akpu;ock(cbio(pbioc(738EDECBFBFD16EE6F202F9C04FA428E)pbioh(7E070B37258FE14790D46687D0094CD04C20A7FC06CC69E89272313665956602)));odel(true);osgn(cbio(pbioc(738EDECBFBFD16EE6F202F9C04FA428E)pbioh(7E070B37258FE14790D46687D0094CD04C20A7FC06CC69E89272313665956602)));oa(true)>
    
  • Public key kSecAttrAccessControl:

    <SecAccessControlRef: akpu>
    

Behavior after disabling biometrics (Touch ID): The key pair remains accessible.

Behavior after disabling the device passcode:

  • The private key is still accessible.
  • The public key results in errSecItemNotFound.

This behavior is indeed puzzling.

Any insights you can share about this inconsistency would be greatly appreciated!

Secure Enclave Key Persistence When Passcode is Removed
 
 
Q