Key attestation and app’s integrity check in iOS.
1.Background
Android has the feature for key integrity verification recently Apple has also introduce DCAppAttest Service
in iOS 14 onwards to verify the app and key integrity. Basically you can’t rely on your app’s logic to perform security checks on itself because a compromised app can falsify the results.Hence this Apple provides a way to create a hardware-based, cryptographic key that uses Apple servers to certify that the key belongs to a valid instance of your app.
Using this hardware-based cryptographic key apps achieve better security .
a. Validating app instance connecting to server .
b. Assessing and limiting the fraud risk.

2.Implementation Overview
DCAppAttestService is only available from iOS 14 onwards hence it is recommended to check for support before you use this service . If the user’s app doesn’t pass the compatibility check, gracefully bypass the service.
2.1.Check for Availability. Not all devices can use the App Attest service, so it’s important to have your app run a compatibility check before accessing the service. If the user’s app doesn’t pass the compatibility check, gracefully bypass the service. You check for availability by reading the isSupported
property:
2.2.Create a Key Pair . Create hardware-based, cryptographic key pair by calling the generateKey(completionHandler:)
method:
On success, the method’s completion handler returns a key identifier that you use later to access the key. Store the identifier in persistent storage — for example, by writing it to a file — because there’s no way to use the key without the identifier, and no way to get the identifier later.
2.3.Certify the Key Pair as Valid. Before using a key pair, ask Apple to attest to its origin on Apple hardware running an uncompromised version of your app. Because you can’t trust your app’s logic to verify the attestation result, you send the result to your server. To reduce the risk of replay attacks during this procedure, attestation embeds the hash of a unique, one-time challenge from your server. You can create a suitable value using the SHA256
implementation in CryptoKit:
2.4. Implementation in Swift .

3.Assert future server requests using. After successfully verifying a key’s attestation, your server can require the app to assert its legitimacy for any or all future server requests. The app does this by signing the request. In the app, first obtain a unique, one-time challenge from the server. You use a challenge here, like for attestation, to avoid replay attacks. Then combine the challenge with the server request to create a hash:
challenge = <# A string from your server #>
let request = [ "action": "getGameLevel", "levelId": "1234", "challenge": challenge ]guard let clientData = try? JSONEncoder().encode(request) else { return }let clientDataHash = Data(SHA256.hash(data: clientData))
Use this hash and the key identifier that you generated earlier to create an assertion object by calling the generateAssertion(_:clientDataHash:completionHandler:)
method:
service.generateAssertion(keyId, clientDataHash: clientDataHash) { assertion, error in guard error == nil else { /* Handle the error. */ } // Send the assertion and request to your server.}