I'd like to prevent an attacker who uses a jailbroken iPhone or iPad from reading the contents of the Keychain of my app.
Is there any point in using the Secure Enclave to generate a public-private key pair if an attacker with a jailbroken device can easily attach a debugger to my app, read from the Keychain of my app and also request decryption via the Secure Enclave while appearing to the Secure Enclave as my genuine app?
Doesn't the whole security of the Keychain stand on the assumption that an attacker cannot attach a debugger to my app?
Is there really no reliable way how to prevent someone from attaching a debugger to my app? I think that using PT_DENY_ATTACH is very easily bypassed by attackers.
I don't mind if someone attaches a debugger to a re-signed version of my app, because such re-signed app would have a different Team ID, so the Secure Enclave would fail when attempting to use the key generated by my genuine app.
I just want to prevent the situation when an attacker could read from the Keychain of my app and request the Secure Enclave to apply the private keys which were generated by my genuine app.
Is the Keychain and the Secure Enclave essentially worthless on jailbroken devices if a determined attacker wants to take control of my app running on their jailbroken device?
I’m reluctant to talk about jailbreaking because it’s a complex situation with poor terminology that evolves rapidly. Fortunately, there’s a different context where we can talk about this sort of thing, namely a Mac with System Integrity Protection disabled. And while you’re not targeting the Mac, it’s reasonable to draw analogies between the two situations.
On a Mac with SIP disabled the user can replace the kernel. That’s problematic because it puts you in a situation where your code is trying to protect itself from code running at a higher privilege. That’s not possible in the general, primarily because you can’t trust your own code. Basic functionality, like checking the hash of code pages being brought in from disk, is no longer trustworthy, so you can’t be sure that any checks that you do are actually going to run.
Which isn’t to say that the SE-protected credentials are useless. If you use them to communicate with a server, then the combination of SE protection and App Attest is useful signal.
Oh, and I want to speak to this:
re-signed app would have a different Team ID, so the Secure Enclave would fail when attempting to use the key generated by my genuine app.
That’s not how this pans out. When you store an SE-protected key in the keychain, it’s the keychain that ensures that only your app can access it, based on the entitlements described in Sharing access to keychain items among a collection of apps. The consequences are the same, but the mechanics are different.
Finally, I’m gonna recommend that you read Apple Platform Security. It has a lot of detailed info on how security is implement on iOS, and if any of my answers are misaligned with it then it’s likely that it’s right and I’m wrong (-:
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"