I heard and read in reddit and GitHub about that UIDevice.current.identifierForVendor.uuidString is restricted according to privacy. Its better use DeviceCheck API or create my own UUID. So is it correct? If its so please can you share apple privacy update about this?
DeviceCheck
RSS for tagAccess per-device, per-developer data that your associated server can use in its business logic using DeviceCheck.
Posts under DeviceCheck tag
15 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
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
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?
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
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.
Whenever we call this API enpoint https://api.development.devicecheck.apple.com/v1/validate_device_token we received an 403. The issue started yesterday around 2:00 PM (Brasil - Brasília time).
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
In our Enterprise account with Admin access, I can't see the option to create a DeviceCheck key needed for the App Attest functionality.
Is there a limitation preventing this key from being generated on Enterprise accounts?
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?
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!
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.
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.
response body is "service discovery failure"
It appeared by chance.. Does anyone know why?
A lot of our customers experienced failed App attest and always return error "DCErrorInvalidKey 3" invalidKey error on these iOS versions:
16.7.2 - iPhone 8
17.1.1, 17.1.2 - iPhone X, iPhone XS, iPhone XR, iPhone SE 2. iPhone 12, iPhone 12 Pro, iPhone 12 Pro Ma
i need to install a ipa file without apple id and in offline mode for my users (and)
by using usbmuxd i want command to enable the developer mode by using commands only not manually