App Attest

RSS for tag

Validate the integrity of your app before your server provides access to sensitive data.

App Attest Documentation

Posts under App Attest tag

22 Posts
Sort by:
Post not yet marked as solved
2 Replies
269 Views
I have an App Attest server implementation which is generally functioning well. From time to time, however, I get receipts which do not refresh when I send them to Apple's server; I get a 404 response. The docs (https://developer.apple.com/documentation/devicecheck/assessing_fraud_risk?language=objc - "Understanding HTTP Response Codes") say this means "No data available for the supplied receipt". Once a receipt is in this state it seems "stuck" i.e. it will never return a new receipt. I have seen this for both the development and production environments. Does anyone know what this means, and what I should do?
Posted
by endecotp.
Last updated
.
Post not yet marked as solved
0 Replies
115 Views
If I delete an integrity in my settings on my phone can I re verify the integrity? I have tried to re-get the app and try to verify it again but it just won’t pop up to where I can verify the integrity again.
Posted
by Polcer.
Last updated
.
Post not yet marked as solved
1 Replies
347 Views
Hello, I'm trying to submit my game to the app store, but I get rejected with the message: The package I use is iOS 14 Advertising Support package: I use the sample scene from the package with little adjustments: [ContextScreenManager.cs] using UnityEngine; using System; using System.Collections.Generic; #if UNITY_IOS using UnityEngine.iOS; #endif using System.Collections; using UnityEngine.SceneManagement; namespace Unity.Advertisement.IosSupport.Samples { /// <summary> /// This component will trigger the context screen to appear when the scene starts, /// if the user hasn't already responded to the iOS tracking dialog. /// </summary> public class ContextScreenManager : MonoBehaviour { /// <summary> /// The prefab that will be instantiated by this component. /// The prefab has to have an ContextScreenView component on its root GameObject. /// </summary> public ContextScreenView contextScreenPrefab; void Start() { #if UNITY_IOS Debug.Log("IOS detected"); // check with iOS to see if the user has accepted or declined tracking var status = ATTrackingStatusBinding.GetAuthorizationTrackingStatus(); Version currentVersion = new Version(Device.systemVersion); Version ios14 = new Version("14.5"); if (status == ATTrackingStatusBinding.AuthorizationTrackingStatus.NOT_DETERMINED && currentVersion >= ios14) { var contextScreen = Instantiate(contextScreenPrefab).GetComponent<ContextScreenView>(); // after the Continue button is pressed, and the tracking request // has been sent, automatically destroy the popup to conserve memory contextScreen.sentTrackingAuthorizationRequest += () => Destroy(contextScreen.gameObject); } #else Debug.Log("Unity iOS Support: App Tracking Transparency status not checked, because the platform is not iOS."); #endif StartCoroutine(LoadNextScene()); } private IEnumerator LoadNextScene() { #if UNITY_IOS var status = ATTrackingStatusBinding.GetAuthorizationTrackingStatus(); while (status == ATTrackingStatusBinding.AuthorizationTrackingStatus.NOT_DETERMINED) { status = ATTrackingStatusBinding.GetAuthorizationTrackingStatus(); yield return null; } #endif SceneManager.LoadScene(1); yield return null; } } } and [ContextScreenView.cs] using UnityEngine; namespace Unity.Advertisement.IosSupport.Components { /// <summary> /// This component controls an iOS App Tracking Transparency context screen. /// You should only have one of these in your app. /// </summary> public sealed class ContextScreenView : MonoBehaviour { /// <summary> /// This event will be invoked after the ContinueButton is clicked /// and after the tracking authorization request has been sent. /// It's a good idea to subscribe to this event so you can destroy /// this GameObject to free up memory after it's no longer needed. /// Once the tracking authorization request has been sent, there's no /// need for this popup again until the app is uninstalled and reinstalled. /// </summary> public event Action sentTrackingAuthorizationRequest; public void RequestAuthorizationTracking() { #if UNITY_IOS Debug.Log("Unity iOS Support: Requesting iOS App Tracking Transparency native dialog."); ATTrackingStatusBinding.RequestAuthorizationTracking(AuthorizationTrackingReceived); sentTrackingAuthorizationRequest?.Invoke(); #else Debug.LogWarning("Unity iOS Support: Tried to request iOS App Tracking Transparency native dialog, " + "but the current platform is not iOS."); #endif } private void AuthorizationTrackingReceived(int status) { Debug.LogFormat("Tracking status received: {0}", status); } } } Why do I get rejected? Is it because I display the example screens from the package? Anyone had similar problems? Glad for any help, thanks!
Posted
by MosiGames.
Last updated
.
Post not yet marked as solved
0 Replies
139 Views
Hi, Is there a default timeout for the attestKey method? From doc: If the method’s completion handler returns the serverUnavailable error — typically due to network connectivity issues — it means that the framework failed to reach the App Attest service to complete the attestation Br, Johan
Posted
by johw.
Last updated
.
Post not yet marked as solved
0 Replies
189 Views
Dear Experts, Where is the best place to persist an App Attest key id? The docs ( https://developer.apple.com/documentation/devicecheck/establishing_your_app_s_integrity ) say “Record the identifier in persistent storage — for example, by writing it to a file”. That is what I have done, but I have encountered a problem. If a user gets a new device and restores a backup of an old device onto it, the new device will try to use the key id from the old device - which is of course wrong. One solution is to detect the error when the invalid key is used and to generate a new one. Is that the best approach? I am wondering if there is some part of the filesystem that does not survive the backup/restore process, but is otherwise persistent? It should be more persistent than a cache file. (Also looking at the docs again I now see that I am supposed to store distinct keys for each “user”. What is meant by “user” in this case?) Thanks.
Posted
by endecotp.
Last updated
.
Post marked as solved
2 Replies
328 Views
Hello, I've already made a previous similar post but it's getting a bit old so I'm re-launching it. I am currently developing an iOS application using AppCheck with AppAttest. I have read Apple's documentation on AppAttest to understand how it works. However, there is a part I didn't understand. When the public key is to be shared, Apple will create a certificate to attest that this public key belongs to an official instance of my application. Here is what it says about this verification on the official website : How does the Apple server identify that the key comes from an official instance of my application ? I can also rephrase my question as follows: How does the apple server detect an unofficial instance of my application if the data it receives for this check comes from it directly (I assume and I am probably wrong) and can therefore be falsified ? Is this a secret process to which I cannot have access, this answer would also suit me ? Thanks for your attention !
Posted
by Sheezen.
Last updated
.
Post not yet marked as solved
1 Replies
786 Views
We see appAttest (available iOS 14+) provides us 3 key features: if app instance is not modified, device is genuine apple device and payload is not tempered with. We also have deviceCheck Api (iOS 11+) which return 2 bits per device, as mentioned in documentation we can create different payloads for validation and different for updating the 2 bits. Apart from returning those bits in validation request, does this DeviceCheck APIs also validate 2 of the 3 above features i.e. app is not modified and the device is genuine apple device? If yes, what response from apple server to look for in successful validation of above 2 features and what response to look for in fraud cases or failure cases? Does isSupported in case of DCDevice.current hints the device is a simulator ? Can we get exhaustive list of cases where isSupported is false? Does DCDevice.current.generateToken fails only in case of modified app instance? Can we get exhaustive list of cases where above can throw error? Can modified app instance also able to generateToken?
Posted Last updated
.
Post not yet marked as solved
1 Replies
261 Views
According to documentation, the guideline is as follows - "Don’t reuse a key among multiple users on a device because this weakens security protections. In particular, it becomes hard to detect an attack that uses a single compromised device to serve multiple remote users running a compromised version of your app." This can be addressed if we keep a tally of how many users have used the same key pair? If we see a single key pair in use across say 500 users, it's clearly an instance of compromised device. Are there other security reasons why binding a key to device + user is the recommended practice?
Posted Last updated
.
Post not yet marked as solved
0 Replies
224 Views
Apple team, I need your help. Can you answer for my question in thread: https://developer.apple.com/forums/thread/701876 ? I created new thread due to I wasn't able to add tag wwdc21-10244 in thread 701876.
Posted
by Fman.
Last updated
.
Post not yet marked as solved
0 Replies
361 Views
Hi, I'm trying to validate device token generated on app which is signed by Enterprise account. I generate deviceToken on device I send the token to our backend Our backend creates JWT token The backend calls validate_device_token endpoint and receives 401 The authentication token can't be verified I've seen many implementations on the internet and I'm pretty sure that we generate the token in correct way. (eg implementation: https://github.com/marinosoftware/DeviceCheckSample) The Questions are: Is it possible to use DeviceCheck on Enterprise Account ? There is no possibility to enable DeviceCheck on Enterprise account is APNs key configuration: https://developer.apple.com/account/resources/authkeys/list. Is this configuration required ? Is there is a way to validate signature of JWT token locally ? Services such as https://jwt.io requires Public and Private keys in correct format, I didn't find a way to validate the signature signed by p8 certificate without any additional keys.
Posted
by Fman.
Last updated
.
Post not yet marked as solved
1 Replies
324 Views
Hi! Sometimes when calling DCAppAttestService.shared.generateAssertion(key.id, clientDataHash: hash) I'm getting DCError.Code.invalidInput. I am formatting clientDataHash usingSHA256.hash - so it is always 32 bytes long. As I found out - this error depends on hash that I pass to generateAssertion method. But I could not find any system - which hashes are good and which are not. Keys are always correct, otherwise invalidKey error would be risen. What can cause the issue? I'm testing on iPhone 11, iOS 15.2.1
Posted
by beetlab.
Last updated
.
Post not yet marked as solved
1 Replies
744 Views
Hi, We have a multi-platform application that requires integrity attestation before the backend will enable supporting services (fairly common scenario). I've read the documentation for DeviceCheck and AppAttest, as well as SafetyNet on the Android side. The Android documentation includes lots of examples of use, including server-side (though oddly in C# and Javascript... which I don't see as being server-side languages, but... oh, well). Anyway, maybe there's a server-side example of using an application attestation on the server when validating a client, as well as validating individual requests with assertions, but I've not been able to find it. It seems like a relatively important bit of functionality to ensure that apps aren't being compromised, while at the same time requiring a correct implementation... Why not give a reference implementation as a starting point to make sure developers are on the right path? Can anyone point me at an example as a Gist, etc? Thanks.
Posted
by PhilipTP.
Last updated
.
Post not yet marked as solved
0 Replies
233 Views
Hi, I have add UDID for me to install the Test Environment. However, after being installed it show this message. How to solve this ?
Posted
by QuanZhang.
Last updated
.
Post not yet marked as solved
1 Replies
321 Views
Hi. I'm trying to implement App Attest on my App and I followed the guidelines from https://developer.apple.com/documentation/devicecheck/validating_apps_that_connect_to_your_server but step 5 isn't waking. I got an example from https://blog.restlesslabs.com/john/ios-app-attest to implement all 9 steps using Python. Is there any example of this server-side implementation so I can double check what's wrong? PS: I saw one in Kotlin but that doesn't help me. I'm testing on an iPhone X and I can get the key identifier, the challenge and the attestation object. All steps except 5 are working (well, I had to base64 decode the identifier for step 9). Please, any help is appreciated. Regards, Cassio
Posted
by kasros.
Last updated
.
Post not yet marked as solved
1 Replies
756 Views
According to the App Check Firebase Documentation, it is said to add the App Attest capability to your app. However, I am not able to find any such capability in XCode. Any insights on this? Note: We have enabled capability in the provision profiles Documentation Link: https://firebase.google.com/docs/app-check/ios/app-attest-provider#install-sdk
Posted Last updated
.
Post not yet marked as solved
2 Replies
494 Views
Hello, I am sending valid base64 receipt data to Apple on the https://data-development.appattest.apple.com/v1/attestationData endpoint and am getting 400 bad request. I have a valid JWT that I currently use successfully for other DeviceCheck endpoints such as persistent bits. Any help debugging would be useful. Thanks
Posted
by nisargap.
Last updated
.
Post not yet marked as solved
2 Replies
1k Views
Hello, I'm implementing AppAttest for one of our apps. Though the Attestation procedure works fine, the assertion signed by the private key on the device (via generateAssertion) can't be verified at the server with the public key saved during the attestation. Environment AppAttest entitlement: development iOS 14 Server: Nodejs The client (app) and server code specific to assertion is below. Client side code (app) if let clientData = self.prepareClientData(withChallenge: challenge) { &#9;&#9;// generate assertion &#9;&#9;let clientDataHash = Data(SHA256.hash(data: clientData)) &#9;&#9;DCAppAttestService.shared.generateAssertion(keyId!, clientDataHash: clientDataHash) { assertion, error in &#9;&#9;&#9;&#9;guard error == nil else { &#9;&#9;&#9;&#9;&#9;&#9;print ("ERROR: Assertion not available right now") &#9;&#9;&#9;&#9;&#9;&#9;return &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;// create assertion request &#9;&#9;&#9;&#9;var urlRequest = URLRequest(url: URL(string: self.assertEP)!) &#9;&#9;&#9;&#9;urlRequest.httpMethod = "POST" &#9;&#9;&#9;&#9;urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type") &#9;&#9;&#9;&#9;let clientDataString = clientData.base64EncodedString() &#9;&#9;&#9;&#9;let assertionString = assertion!.base64EncodedString() &#9;&#9;&#9;&#9;let assertRequest: [String: Any] = ["clientData": clientDataString, "assertion": assertionString] &#9;&#9;&#9;&#9;let jsonData: Data &#9;&#9;&#9;&#9;do { &#9;&#9;&#9;&#9;&#9;&#9;jsonData = try JSONSerialization.data(withJSONObject: assertRequest, options: []) &#9;&#9;&#9;&#9;&#9;&#9;urlRequest.httpBody = jsonData &#9;&#9;&#9;&#9;} catch { &#9;&#9;&#9;&#9;&#9;&#9;print (error) &#9;&#9;&#9;&#9;&#9;&#9;return &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;// send assertion request to server &#9;&#9;&#9;&#9;let task = URLSession.shared.dataTask(with: urlRequest) { data, response, error in &#9;&#9;&#9;&#9;&#9;&#9;guard error == nil else { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;// request sending failed, try again later &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;print (error!) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;return &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;&#9;&#9;self.extractAssertionResponse(withData: data) &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;task.resume() &#9;&#9;} } Server side Assertion verification code function verifyAssertion(clientDataBuffer, assertionBuffer) { &#9;&#9;try { &#9;&#9;&#9;&#9;let assert = cbor.decodeAllSync(assertionBuffer)[0]; &#9;&#9;&#9;&#9;let authData = assert.authenticatorData; // buffer &#9;&#9;&#9;&#9;let signature = assert.signature; // buffer &#9;&#9;&#9;&#9;// compute client Data Hash &#9;&#9;&#9;&#9;let clientDataHash = crypto.createHash('sha256').update(clientDataBuffer).digest('base64'); &#9;&#9;&#9;&#9;let clientDataHashBuffer = Buffer.from(clientDataHash, 'base64'); &#9;&#9;&#9;&#9;// compute composite hash &#9;&#9;&#9;&#9;let compositeBuffer = Buffer.concat([authData, clientDataHashBuffer]); &#9;&#9;&#9;&#9;let nonce = crypto.createHash('sha256').update(compositeBuffer).digest('base64'); // base64 string &#9;&#9;&#9;&#9;let nonceBuffer = Buffer.from(nonce, 'base64'); &#9;&#9;&#9;&#9;// load public key &#9;&#9;&#9;&#9;let keyObj = crypto.createPublicKey(k_publicKeyPem); &#9;&#9;&#9;&#9;// verify signature &#9;&#9;&#9;&#9;let verifier = crypto.createVerify('sha256').update(nonceBuffer); &#9;&#9;&#9;&#9;let sign_verify = verifier.verify(keyObj, signature); &#9;&#9;&#9;&#9;console.log("sign_verify: ", sign_verify); &#9;&#9;} catch (e) { &#9;&#9;&#9;&#9;console.log(e); &#9;&#9;} } The verifier.verify() call always results in 'false'. I've tried 'hex' and 'base64' variations on the signature, but didn't work. I've verified that the sha256(publicKey) received at the server is equal to the keyId. let keybuf = Buffer.from(k_publicKeyRaw, 'base64'); let keySHA = crypto.createHash('sha256').update(keybuf).digest('base64'); let keyVerified = (keySHA === k_keyId); Also verified that the clientDataHash generated at the server is the same as clientDataHash generated within the app. Does crypto Verify not compatible with the generated signatures? If not, what's the suggested way to do it? I've tried all the encodings supported by crypto Verify.verify but none of those worked. crypto.getHashes(); Please help.
Posted
by vag.
Last updated
.
Post not yet marked as solved
1 Replies
843 Views
In the WWDC 2021 session Mitigate fraud with App Attest and DeviceCheck it is said that: App Attest is supported on devices that have a Secure Enclave, but there are cases, such as app extensions, where isSupported will still return false. The documentation shows that the following Macs have a Secure Enclave: MacBook Pro computers with Touch Bar (2016 and 2017) that contain the Apple T1 Chip Intel-based Mac computers that contain the Apple T2 Security Chip Mac computers with Apple silicon I'm using a 2018 15" MacBook Pro containing a T2 Security Chip for testing, however, DCAppAttestService.shared.isSupported always returns false in native macOS or Catalyst apps. DCDevice.current.isSupported also returns false. The documentation for DCAppAttestService shows availability on "macOS 11.0+" and "Mac Catalyst 14.0+". It appears to have been added in the macOS 11.3 SDK included in Xcode 12.5. DCDevice shows availability on "macOS 10.15+" and "Mac Catalyst 13.0+". Although both APIs are available on the listed OSes, I only ever see isSupported == false. Are App Attest or DeviceCheck functional on any Macs? If so: Are there more specific Macs that support the feature (e.g., Apple Silicon Macs only)? Are there any additional steps that need to be taken to use them (e.g., changes to entitlements, provisioning profiles or distribution through the Mac App Store)? In native macOS apps, it doesn't actually appear to be possible to add the App Attest capability in Xcode under "Signing & Capabilities". If not, I think it would be good to update the documentation with this limitation since I'd expect them to work based on the availability being "macOS 10.15+" or "macOS 11.0+" for DeviceCheck and App Attest, respectively. I imagine most others would make the same assumptions.
Posted
by wizheard.
Last updated
.
Post not yet marked as solved
0 Replies
513 Views
I'm looking at a development attestation for an app we're developing in-house, and there's a couple of undocumented PEN's being used: Certificate:     Data:         Version: 3 (0x2)         Serial Number: 1631564652467 (0x17be0d4dfb3)         Signature Algorithm: ecdsa-with-SHA256         Issuer: CN = Apple App Attestation CA 1, O = Apple Inc., ST = California         Validity             Not Before: Sep 12 20:24:12 2021 GMT             Not After : Sep 15 20:24:12 2021 GMT         Subject: CN = a203e1588ab36ae2ffc362491c2948df5d03f3ed048d0c58a59c9e085724353c, OU = AAA Certification, O = Apple Inc., ST = California         Subject Public Key Info:             Public Key Algorithm: id-ecPublicKey                 Public-Key: (256 bit)                 pub:                     04:09:1a:ae:9f:d2:0b:89:e6:6b:ab:68:3e:70:e1:                     6d:0f:b1:2f:8b:4b:bd:c9:d2:54:ec:15:2c:b4:fc:                     4c:8d:fb:e1:49:0d:90:34:80:10:82:08:6c:49:58:                     7e:2c:5b:90:2b:80:2d:1f:f3:e9:36:59:51:d2:3e:                     1d:d2:f8:75:e3                 ASN1 OID: prime256v1                 NIST CURVE: P-256         X509v3 extensions:             X509v3 Basic Constraints: critical                 CA:FALSE             X509v3 Key Usage: critical                 Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment             1.2.840.113635.100.8.5:      0:d=0  hl=2 l= 111 cons: SEQUENCE               2:d=1  hl=2 l=   3 cons:  cont [ 4 ]             4:d=2  hl=2 l=   1 prim:   INTEGER           :0A     7:d=1  hl=4 l=   3 cons:  cont [ 1200 ]         11:d=2  hl=2 l=   1 prim:   INTEGER           :01    14:d=1  hl=4 l=   3 cons:  cont [ 1201 ]         18:d=2  hl=2 l=   1 prim:   INTEGER           :00    21:d=1  hl=4 l=   3 cons:  cont [ 1202 ]         25:d=2  hl=2 l=   1 prim:   INTEGER           :01    28:d=1  hl=4 l=   3 cons:  cont [ 1203 ]         32:d=2  hl=2 l=   1 prim:   INTEGER           :01    35:d=1  hl=4 l=  38 cons:  cont [ 1204 ]         39:d=2  hl=2 l=  36 prim:   OCTET STRING      :XKXEK7P8ZU.com.truepic.appattestdemo    77:d=1  hl=2 l=   6 cons:  cont [ 5 ]            79:d=2  hl=2 l=   4 prim:   OCTET STRING      :sks     85:d=1  hl=4 l=   3 cons:  cont [ 1206 ]         89:d=2  hl=2 l=   1 prim:   INTEGER           :05    92:d=1  hl=4 l=   3 cons:  cont [ 1207 ]         96:d=2  hl=2 l=   1 prim:   INTEGER           :00    99:d=1  hl=4 l=   3 cons:  cont [ 1209 ]        103:d=2  hl=2 l=   1 prim:   INTEGER           :00   106:d=1  hl=4 l=   3 cons:  cont [ 1210 ]        110:d=2  hl=2 l=   1 prim:   INTEGER           :00             1.2.840.113635.100.8.7:      0:d=0  hl=2 l=   6 cons: SEQUENCE               2:d=1  hl=4 l=   2 cons:  cont [ 1400 ]          6:d=2  hl=2 l=   0 prim:   OCTET STRING                   1.2.840.113635.100.8.2:      0:d=0  hl=2 l=  36 cons: SEQUENCE               2:d=1  hl=2 l=  34 cons:  cont [ 1 ]             4:d=2  hl=2 l=  32 prim:   OCTET STRING             0000 - 52 93 c9 c6 69 4e 74 3c-63 13 4b d0 0a 92 12 87   R...iNt&lt;c.K.....       0010 - 36 64 cf c3 3d 8d c0 5b-3b 26 72 5a a4 5a ab 71   6d..=..[;&amp;rZ.Z.q     Signature Algorithm: ecdsa-with-SHA256          30:65:02:31:00:d0:40:c9:18:68:10:c7:0d:2a:04:31:9a:38:          74:7a:ee:1e:a3:da:a3:58:05:0f:15:ae:86:9e:19:07:b8:d3:          67:fc:c1:3f:e4:c2:eb:1b:37:d5:b1:c3:6f:df:52:da:c0:02:          30:5b:8e:d8:67:9e:5d:59:64:68:bf:85:a8:a7:ae:e8:a8:e4:          06:f0:df:75:c5:e8:7e:0a:d4:24:64:e8:6c:c3:2d:ac:31:bf:          3f:d1:78:a7:00:ff:11:31:1b:28:08:27:5d .2 I get. It's documented in Validating Apps That Connect to Your Server. Some GitHub gists suggest that .7 is supposed to be an Octet String containing the iOS version number, but it's empty in our case. Unclear why. No idea what .5 is supposed to be. Does anyone have any insight into these last two? Also, how does one determine the particular that's generating the attestation? Android SafetyNet attestation generates a unique hash (as the list of SHA256's in apkCertificateDigestSha256); it seems to me that we might want to further fine-tune the handling of sensitive operations based on the specifics of the version. Lastly, the above cited documentation states, in the "Store the Public Key and Receipt" section: Store the verified public key from credCert on your server and associate it with the user for the specific device. You use this key to check assertions later. But iOS (and iPadOS) doesn't support multiple accounts per device. So I'm interpreting this to not refer to an associated AppleID, but rather credentials in some app-specific space defined by the app developer. Is that correct? Thanks
Posted
by PhilipTP.
Last updated
.