DeviceCheck

RSS for tag

Access per-device, per-developer data that your associated server can use in its business logic using DeviceCheck.

Posts under DeviceCheck tag

16 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Getting 400 response for every time appAttestation url
The token is legitimate, however I keep getting bad requests (400). The payload may not be accurate. No document with the appropriate payload structure is visible to me. Receipt.bin was tried, but the file content could not be verified. Referring this URL: https://developer.apple.com/documentation/devicecheck/assessing-fraud-risk Here is my server side Java code: private static String sendAttestationWithPayload(String jwt, String keyId, String attestationData, String clientData) throws Exception { // Create JSON payload JSONObject payload = new JSONObject(); payload.put("keyId", keyId); payload.put("attestationData", attestationData); payload.put("clientData", clientData); HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(APPLE_ATTESTATION_URL)) .header("Authorization", "Bearer " + jwt) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(payload.toString())) .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); handleResponse(response); return response.body(); }
0
0
118
1w
How to get in contact with team that manages DeviceCheck
Hi, I run a service that protects API calls from Apple ecosystem apps with several layers of security, one of them being DeviceCheck's server-to-server functionality. All requests arrive with a DeviceCheck token that I send to Apple to validate. Essentially I'm using the functionality listed here: The server-to-server APIs also let you verify that the token you receive comes from your app on an Apple device. https://developer.apple.com/documentation/devicecheck However, occasionally I see huge bursts of traffic that contain valid DeviceCheck tokens from a scripter. I want to understand how they are generating them. It seems like they have identified a way to forge tokens. Here are traffic patterns for my site. The scale of the y-axis is somewhat arbitrary due to how I'm sampling the requests, but you get the gist. You can see the dark green bars at the bottom are general traffic, and the light green is what we rejected (we have other layers besides DeviceCheck that reject traffic). Interestingly, though, all those light green requests contained valid device check tokens! I have thousands of the tokens stored in a file for analysis. Are there known ways that Apple knows of tokens being forged? I wanted to open a TSI for this but the flow requires an Xcode project, and there is no Xcode project to demonstrate this issue. I would really like to get in contact with someone from Apple that either works on DeviceCheck or supports it. Hundreds of apps in the store depend on my service, and DeviceCheck forms a layer of security that I want to rely on. Obviously we can't solely rely on it, and we don't, but it does form an important layer of our defense. So I ask: If you know of a way to forge tokens, please comment and I'll shoot you a DM If you work at Apple and know who I can talk to, please help me work through the process to get in touch with them. Thanks, Lou
5
0
173
2w
Device Token Validity in Device Check and App attestation validity in App Attestation
We are trying to integrate "Device Check" and "Device Check - App attest" services to check device integrity and app integrity. We read apple documentation and could not locate the TTL(time-to live) for "Device Token" and "App Attestation Object". Could you let us what TTL for Device Token" and "App Attestation Object"? We can design our architecture based on your answer
1
0
268
Oct ’24
App Attest fails only for App built with M processor
We are having trouble with App Attest when built with different processors. We need to build an IPA to send to our testers. When the app is built using Intel processor, everything works. But when we built using a mac with processor M, them the App Attest process fails. The error occurs in our backend while validating the attesation object. We are doing the validation as stated by this documentation: https://developer.apple.com/documentation/devicecheck/attestation-object-validation-guide The process of validating the Attesation Object fails in the step 4, this one: Obtain the value of the credCert extension with OID 1.2.840.113635.100.8.2, which is a DER-encoded ASN.1 sequence. Decode the sequence and extract the single octet string that it contains. Verify that the string equals nonce. The problem is that the validation fails only when the app is built in a M processor machine. In our server we do (using GO Lang) something like this: if !bytes.Equal(nonce[:], unMarshalledCredCert.Bytes) { // error } unMarshalledCredCert is the nonce extracted from the Attesation Object sent by the mobile application and nonce[:] is the nonce stored in our backend side cache. What can this be?
0
0
375
Aug ’24
iOS DeviceCheck API call returning 400 all the time
Hi, I'm getting 400 Missing or badly formatted authorization token everytime I call the following API from my local Server ( I tried calling this API from my app itself as well) curl --location 'https://api.development.devicecheck.apple.com/v1/query_two_bits' \ --header 'Authorization: Bearer <<JWT-token>>' \ --header 'Content-Type: application/json' \ --data '{ "device_token": Token_fetched_from_Device_Check, "transaction_id":"c6bdb659-0ee6-443d-88cb-a8f036dfc551", "timestamp": 1721300244267 }' "device_token" - I have generated from DeviceCheck framework JWT-token - I generated using key from .p8 file generated from Apple developer portal, keyId of the same and the team Id ( I have individual account) IMP Points- I have created this .p8 file from apple developer account, and I did enable Device check option while creating the key. I also tried calling this API after 7 hours ( and more then that as well) of creating key from the developer portal as I have read somewhere that the key gets activated after few hours. I understand (again read somewhere) that the token created by DeviceCheck framework has some expiration time so I tried with freshly created token several times as well. This is how I'm generating token using DeviceCheck - if curDevice.isSupported{ DCDevice.current.generateToken { (data, error) in if let data = data { } } } JWT token generation - func createJWTToken(privateKey: String, keyID: String, teamID: String) -> String? { // Set up the JWT header var jwtHeader = Header() jwtHeader.kid = keyID // Set up the JWT claims let jwtClaims = MyClaims(iss: teamID, iat: Date()) // Create the JWT var jwt = JWT(header: jwtHeader, claims: jwtClaims) // Convert the private key to Data guard let privateKeyData = Data(base64Encoded: privateKey) else { print("Invalid private key") return nil } // Sign the JWT let jwtSigner = JWTSigner.es256(privateKey: privateKeyData) do { let signedJWT = try jwt.sign(using: jwtSigner) return signedJWT } catch { print("Failed to sign JWT: \(error)") return nil } } But no luck, please suggest something. any sort of help is much appreciated. Thank you
2
0
613
Jul ’24
App Attest Server Validations
I'm following the attestation object validation guide to check my attestation server validations, but having a different output of that it's expected in the documentation. Everything goes well until the step 2, where it's created the SHA256 hash of the one-time challenge, then this hash it's appended to the end of the authenticator data from the decoded attestation object. Here the generated client data hash is different from the one in the documentation, which also causes a different nonce value. Full implementation at Go Playground: https://go.dev/play/p/DpL_H3L8yWV // generate the SHA256 hash of the one-time challenge challengeHash := sha256.Sum256([]byte(serverChallenge)) // append the one-time challenge hash to the end of the authenticator data clientDataHash := append([]byte(att.AuthData), challengeHash[:]...) // create a SHA256 hash of the composite item to create nonce nonce := sha256.Sum256(clientDataHash) Then I noticed that if the one-time challenge value it's just appended to the end of the authenticator data, the value it's correctly according to the documentation. Full implementation at Go Playground: https://go.dev/play/p/qqN97SevJAB // append the one-time challenge byte array to the end of the authenticator data // this time not generating the SHA256 hash of the one-time challenge clientDataHash := append([]byte(att.AuthData), []byte(serverChallenge)...) // create a SHA256 hash of the composite item to create nonce nonce := sha256.Sum256(clientDataHash) My question is which of the implementations is correct, because if I didn't get it wrong it should be the first one and we would have an error in the documentation.
2
1
714
Jul ’24
Unwanted Communication Reporting Extension - error with classificationreport url
Hi, I'm having headaches with the debugging of my Unwanted Communication Reporting extension. iPhone log says: com.apple.IdentityLookup.MessageFilter[1774] <Error>: Extension's containing app (appID <private>) unauthorized to defer requests to host <private> So I guess I have something wrong with my apple-app-site-association. The AASA file I get with swcutil dl -d services.mydomain.com { classificationreport = { apps = ( "<MYTEAMID>.com.mydomain.myapp", "<MYTEAMID>.com.mydomain.myapp.unwanted" ); }; } where .com.mydomain.myapp is my containing app (bundle id). and .com.mydomain.myapp.unwanted is my extension The AASA file on the server is obviously in JSON format and correctly served from the server : services.mydomain.com In the extension Info.plist I've set the following : <key>NSExtension</key> <dict> <key>NSExtensionAttributes</key> <dict> <key>ILClassificationExtensionNetworkReportDestination</key> <string>https://services.mydomain.com/path/unwanted/report</string> </dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.identitylookup.classification-ui</string> </dict> I suppose the reply from classificationResponse method is correct since MessageFilter "tries" to send the request. Where am I mistakening ? Difficult to debug... MessageFilter's log keeps interesting data as private (so there is no way to check what it's actually doing). And I've found no way to go deeper in the debug process. Many thanks Emmanuel
3
1
677
Jun ’24
[Device Check]Get SSL connection timeout when connect https://api.devicecheck.apple.com
Our service is using Apple device check api to prevent fraud happening. https://developer.apple.com/documentation/devicecheck/accessing-and-modifying-per-device-data But there is SSL connection timeout happen from June 1st. /app $ curl --connect-timeout 5 -v https://api.devicecheck.apple.com Trying 17.33.193.105:443... Connected to api.devicecheck.apple.com (17.33.193.105) port 443 (#0) ALPN, offering h2 ALPN, offering http/1.1 successfully set certificate verify locations: CAfile: /etc/ssl/certs/ca-certificates.crt CApath: none TLSv1.3 (OUT), TLS handshake, Client hello (1): SSL connection timeout Closing connection 0 curl: (28) SSL connection timeout Does apply add access limitation for specific ips?
1
0
465
Jun ’24
DeviceCheck tokens are "single-use" - How do I read and update the bits (2 calls) within the same backend request?
Hey, the documentation for the generateToken() method states: Your server uses the generated token in its requests to get or set the persistent bits for the current device. You should treat the token you receive in the completion block as single-use. Although the token remains valid long enough for your server to retry a specific request if necessary, you should not use a token multiple times. Instead, use this method to generate a new token. Now, what I want to do in my backend is: Read the current bits to decide if an action is allowed If the action is allowed, update the bits That's 2 calls to the DeviceCheck API, so I would need 2 tokens, right? But I want to do this in a single call to my backend. Is it fine for the device to generate send 2 tokens at the same time? Or can I actually use a single token for both calls, and "single-use" just means I should not store it? Thanks!
0
0
468
Apr ’24
Increase in latency in DeviceCheck attestationData endpoint
Hello, Since the 21st of March 2024 around 6PM UTC I've been observing a very significant an increase (more than quadrupled) in P99 and P95 latency on https://data.appattest.apple.com/v1/attestationData I'm calling other endpoints of the same API, and I'm not observing a similar increase there. I tried submitting a report in Feedback Assistant but it's not working for me at the moment.
0
0
667
Mar ’24
Undocumented behavior about risk metric refresh
Hello, I'm developing a server that uses the app attestation feature. During the development, I found the behavior that are not written in the document, I would like to inquire this. When Apple server returns 404 for risk metric refresh request? A month after the attestation, receipt is not past expiration time, but 404 is returned from Apple server when I try refresh. And this receipt succeeded in refreshing the risk metric normally if the attestation proceeds again. This behavior is not in the document, but I wonder if it is intended. Is there a case where an attestation has occurred but the risk metric value does not increase? I found a case where attestation occurred twice on one device, but when both receipts were refreshed, the risk metric returned 1. Is this an expected behavior? If it is, I would like to know the detailed conditions under which it occurs. Thank you.
3
0
882
Jun ’24