A new Apple iOS feature to "attest" an app is healthy.
https://developer.apple.com/documentation/devicecheck
DeviceCheck
launched in the summer of 2020 as part of the iOS 14 release.
On paper, the Public Interface
to the DCAppAttestService Class
is tiny:
var shared: DCAppAttestService
var isSupported: Bool
func generateKey(completionHandler: (String?, Error?) -> Void)
func attestKey(String, clientDataHash: Data, completionHandler: (Data?, Error?) -> Void)
func generateAssertion(String, clientDataHash: Data, completionHandler: (Data?, Error?) -> Void)
But then it becomes apparent there is a sister class: dcdevice
:
class var current: DCDevice
var isSupported: Bool
func generateToken(completionHandler: (Data?, Error?) -> Void)
To use the DCDevice class, the app ID must with this Capability
on developer.apple.com
.
-
Key
generated by App Attest aregenerated
andpersisted
inside the device’sSecurity Enclave
. -
Like other
Secure Enclave
work, the app is never given thePrivate Key
. -
The app is responsible for persisting a
key Identifier
so you can always point theSecure Enclave
to the correctPrivate Key
. -
The app can get a serialized version of the
Public Key
. But, before that happens, you callservice.attestKey
. This makes a call toApple's attestation service
. Apple servers generate anattestation object
and return it to the app. That object can then be passed to your server. -
This
attestation
step is purely anenrolment
step to ensure the app'sApp Attest Public Key
resists tampering. -
Other parts of the
attestation object
additional your server to detectreplay attacks
.
-
The request to Apple's servers can fail. Or forced to fail.
-
if service.isSupported
references aYes/No
Objective-C property that could be swizzled at run-time.