App Attest

RSS for tag

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

Posts under App Attest tag

26 Posts

Post

Replies

Boosts

Views

Activity

Provisioning Profile Defect: App Attest Entitlement (com.apple.developer.app-attest.environment) Missing Despite Enabled Capability
Hello everyone, I'm facing a critical, blocking issue where my developer account (Team ID: K655PX7A46) is unable to generate a valid provisioning profile with the App Attest entitlement. I have confirmed this is a server-side issue and am hoping to get visibility from an Apple engineer who can investigate. The Problem: When I generate a provisioning profile for an App ID with the "App Attest" capability enabled, the resulting profile is defective. It is missing the required com.apple.developer.app-attest.environment key in its entitlements dictionary, causing Xcode to fail the build. What I Have Proven: The issue is not a misconfiguration. The App Attest capability is correctly enabled and saved on the App ID configuration page. The issue is not isolated to one App ID. I created a brand new App ID from scratch, enabled the capability during creation, and the server still generates a defective profile with the same missing entitlement. I have definitive proof by inspecting the downloaded .mobileprovision file. The contents confirm the required key is missing. Steps to Reproduce on My Account: Create a new App ID on the Developer Portal. Enable the "App Attest" capability and save. Generate a new "iOS App Development" provisioning profile for this App ID. Download the profile and inspect its contents via security cms -D -i [profile]. Observe that the com.apple.developer.app-attest.environment key is missing. The Evidence (Contents of the Defective Profile): Here is the output from inspecting the profile for a brand new App ID (com.technology519.linksi.app2). As you can see, the correct entitlement is missing, and an incorrect devicecheck entitlement is present instead. This is a critical bug in the provisioning profile generation service for my account that is blocking all development. I have already filed a support ticket (Case #102721408444) but have so far only received generic, unhelpful responses. Can an Apple engineer please investigate this server-side issue with my account? Thank you.
3
0
502
1w
DCError 2 "Failed to fetch App UUID" - App Attest not working in production or development
Hey everyone, I'm hitting a really frustrating issue with App Attest. My app was working perfectly with DCAppAttestService on October 12th, but starting October 13th it started failing with DCError Code 2 "Failed to fetch App UUID" at DCAppAttestController.m:153. The weird part is I didn't change any code - same implementation, same device, same everything. I've tried switching between development and production entitlement modes, re-registered my device in the Developer Portal, created fresh provisioning profiles with App Attest capability, and verified that my App ID has App Attest enabled. DCAppAttestService.isSupported returns true, so the device supports it. Has anyone else run into this? This is blocking my production launch and I'm not sure if it's something on my end or an Apple infrastructure issue.
0
0
301
2w
Unable to validate app attest assertion signature
I'm trying to setup device attestation. I believe I have everything setup correctly but the final step of signature validation never succeeds. I've added validation on the client side for debugging and it doesn't validate using CryptoKit. After the assertion is created, I try to validate it: assertion = try await DCAppAttestService.shared.generateAssertion(keyId, clientDataHash: clientDataHash) await validateAssertionLocallyForDebugging(keyId: keyId, assertionObject: assertion, clientDataHash: clientDataHash) In the validateAssertionLocallyForDebugging method, I extract all the data from the CBOR assertionObject and then setup the parameters to validate the signature, using the key that was created from the original attestation flow, but it fails every time. I'm getting the public key from the server using a temporary debugging API. let publicKeyData = Data(base64Encoded: publicKeyB64)! let p256PublicKey = try P256.Signing.PublicKey(derRepresentation: publicKeyData) let ecdsaSignature = try P256.Signing.ECDSASignature(derRepresentation: signature) let digestToVerify = SHA256.hash(data: authenticatorData + clientDataHash) print(" - Recreated Digest to Verify: \(Data(digestToVerify).hexDescription)") if p256PublicKey.isValidSignature(ecdsaSignature, for: digestToVerify) { print("[DEBUG] SUCCESS: Local signature validation passed!") } else { print("[DEBUG] FAILED: Local signature validation failed.") } I have checked my .entitlements file and it is set to development. I have checked the keyId and verified the public key. I have verified the public key X,Y, the RP ID Hash, COSE data, and pretty much anything else I could think of. I've also tried using Gemini and Claude to debug this and that just sends me in circles of trying hashed, unhashed, and double hashed clientData. I'm doing this from Xcode on an M3 macbook air to an iPhone 16 Pro Max. Do you have any ideas on why the signature is not validating with everything else appears to be working? Thanks
0
0
463
3w
App Attest attestationData request fails with 400 Bad Request (no X-Request-ID)
Hello Apple Team We are integrating App Attest with our backend and seeing a 400 Bad Request response when calling the attestation endpoint. The issue is that the response does not include an X-Request-ID or JSON error payload with id and code, which makes it hard to diagnose. Instead, it only returns a receipt blob. Request Details URL: https://data-development.appattest.apple.com/v1/attestationData Request Headers: Authorization: eyJraWQiOiI0RjVLSzRGV1JaIiwidHlwIjoiSldUIiwiYWxnIjoiRVMyNTYifQ.eyJpc3MiOiJOOVNVR1pNNjdRIiwiZXhwIjoxNzU3MDUxNTYwLCJpYXQiOjE3NTcwNDc5NjB9.MEQCIF236MqPCl6Vexg7RcPUMK8XQeACXogldnpuiNnGQnzgAiBQqASdbJ64g58xfWGpbzY3iohvxBSO5U5ZE3l87JjfmQ Content-Type: application/octet-stream Request Body: (Binary data, logged as [B@59fd7d35) Response Status: 400 Bad Request Response Headers: Date: Fri, 05 Sep 2025 04:52:40 GMT x-b3-traceid: 4c42e18094022424 x-b3-spanid: 4c42e18094022424 Response Body (truncated): "receipt": h'308006092A864886F70D01070... Problem The response does not include X-Request-ID. The response does not include JSON with id or code. Only a receipt blob is returned. Questions Can the x-b3-traceid be used by Apple to trace this failed request internally? Is it expected for some failures to return only a receipt blob without X-Request-ID? How should we interpret this error so we can handle it properly in production? Thanks in advance for your guidance.
1
0
244
Sep ’25
App Attest Validation Nonce Not Matched
Greetings, We are struggling to implement device binding according to your documentation. We are generation a nonce value in backend like this: public static String generateNonce(int byteLength) { byte[] randomBytes = new byte[byteLength]; new SecureRandom().nextBytes(randomBytes); return Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes); } And our mobile client implement the attestation flow like this: @implementation AppAttestModule - (NSData *)sha256FromString:(NSString *)input { const char *str = [input UTF8String]; unsigned char result[CC_SHA256_DIGEST_LENGTH]; CC_SHA256(str, (CC_LONG)strlen(str), result); return [NSData dataWithBytes:result length:CC_SHA256_DIGEST_LENGTH]; } RCT_EXPORT_MODULE(); RCT_EXPORT_METHOD(generateAttestation:(NSString *)nonce resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { if (@available(iOS 14.0, *)) { DCAppAttestService *service = [DCAppAttestService sharedService]; if (![service isSupported]) { reject(@"not_supported", @"App Attest is not supported on this device.", nil); return; } NSData *nonceData = [self sha256FromString:nonce]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *savedKeyId = [defaults stringForKey:@"AppAttestKeyId"]; NSString *savedAttestation = [defaults stringForKey:@"AppAttestAttestationData"]; void (^resolveWithValues)(NSString *keyId, NSData *assertion, NSString *attestationB64) = ^(NSString *keyId, NSData *assertion, NSString *attestationB64) { NSString *assertionB64 = [assertion base64EncodedStringWithOptions:0]; resolve(@{ @"nonce": nonce, @"signature": assertionB64, @"deviceType": @"IOS", @"attestationData": attestationB64 ?: @"", @"keyId": keyId }); }; void (^handleAssertion)(NSString *keyId, NSString *attestationB64) = ^(NSString *keyId, NSString *attestationB64) { [service generateAssertion:keyId clientDataHash:nonceData completionHandler:^(NSData *assertion, NSError *assertError) { if (!assertion) { reject(@"assertion_error", @"Failed to generate assertion", assertError); return; } resolveWithValues(keyId, assertion, attestationB64); }]; }; if (savedKeyId && savedAttestation) { handleAssertion(savedKeyId, savedAttestation); } else { [service generateKeyWithCompletionHandler:^(NSString *keyId, NSError *keyError) { if (!keyId) { reject(@"keygen_error", @"Failed to generate key", keyError); return; } [service attestKey:keyId clientDataHash:nonceData completionHandler:^(NSData *attestation, NSError *attestError) { if (!attestation) { reject(@"attestation_error", @"Failed to generate attestation", attestError); return; } NSString *attestationB64 = [attestation base64EncodedStringWithOptions:0]; [defaults setObject:keyId forKey:@"AppAttestKeyId"]; [defaults setObject:attestationB64 forKey:@"AppAttestAttestationData"]; [defaults synchronize]; handleAssertion(keyId, attestationB64); }]; }]; } } else { reject(@"ios_version", @"App Attest requires iOS 14+", nil); } } @end For validation we are extracting the nonce from the certificate like this: private static byte[] extractNonceFromAttestationCert(X509Certificate certificate) throws IOException { byte[] extensionValue = certificate.getExtensionValue("1.2.840.113635.100.8.2"); if (Objects.isNull(extensionValue)) { throw new IllegalArgumentException("Apple App Attest nonce extension not found in certificate."); } ASN1Primitive extensionPrimitive = ASN1Primitive.fromByteArray(extensionValue); ASN1OctetString outerOctet = ASN1OctetString.getInstance(extensionPrimitive); ASN1Sequence sequence = (ASN1Sequence) ASN1Primitive.fromByteArray(outerOctet.getOctets()); ASN1TaggedObject taggedObject = (ASN1TaggedObject) sequence.getObjectAt(0); ASN1OctetString nonceOctet = ASN1OctetString.getInstance(taggedObject.getObject()); return nonceOctet.getOctets(); } And for the verification we are using this method: private OptionalMethodResult<Void> verifyNonce(X509Certificate certificate, String expectedNonce, byte[] authData) { byte[] expectedNonceHash; try { byte[] nonceBytes = MessageDigest.getInstance("SHA-256").digest(expectedNonce.getBytes()); byte[] combined = ByteBuffer.allocate(authData.length + nonceBytes.length).put(authData).put(nonceBytes).array(); expectedNonceHash = MessageDigest.getInstance("SHA-256").digest(combined); } catch (NoSuchAlgorithmException e) { log.error("Error while validations iOS attestation: {}", e.getMessage(), e); return OptionalMethodResult.ofError(deviceBindError.getChallengeNotMatchedError()); } byte[] actualNonceFromCert; try { actualNonceFromCert = extractNonceFromAttestationCert(certificate); } catch (Exception e) { log.error("Error while extracting nonce from certificate: {}", e.getMessage(), e); return OptionalMethodResult.ofError(deviceBindError.getChallengeNotMatchedError()); } if (!Arrays.equals(expectedNonceHash, actualNonceFromCert)) { return OptionalMethodResult.ofError(deviceBindError.getChallengeNotMatchedError()); } return OptionalMethodResult.empty(); } But the values did not matched. What are we doing wrong here? Thanks.
1
0
894
Sep ’25
App Attest Error
Hi, I'm running into an issue with App Attest in my iOS app, and I'm hoping you can help me troubleshoot. I've registered my app in App Check for both App Attest and Device Check, and I've double-checked that my bundle ID is correct. I've also enabled App Attest in Xcode capabilities and am testing on a physical device. However, when I run the app, I'm getting the following error in the console: Error getting App Check token; using placeholder token instead. Error: App attestation failed. HTTP status code: 403 "message": "App attestation failed." I've tried a few things, but I'm still stuck. Any suggestions on what might be causing this or how to resolve it would be greatly appreciated! Thanks in advance
1
0
76
Aug ’25
App Attest Issue in Production - Attestation Object Size Increased
Hi Apple Team and Community, We encountered a sudden and widespread failure related to the App Attest service on Friday, July 25, starting at around 9:22 AM UTC. After an extended investigation, our network engineers noted that the size of the attestation objects received from the attestKey call grew in size notably starting at that time. As a result, our firewall began blocking the requests from our app made to our servers with the Base64-encoded attestation objects in the payload, as these requests began triggering our firewall's max request length rule. Could Apple engineers please confirm whether there was any change rolled out by Apple at or around that time that would cause the attestation object size to increase? Can anyone else confirm seeing this? Any insights from Apple or others would be appreciated to ensure continued stability. Thanks!
3
0
172
Jul ’25
DCError.invalidInput on generateAssertion() - Affecting Small Subset of Users
Issue Summary I'm encountering a DCError.invalidInput error when calling DCAppAttestService.shared.generateAssertion() in my App Attest implementation. This issue affects only a small subset of users - the majority of users can successfully complete both attestation and assertion flows without any issues. According to Apple Engineer feedback, there might be a small implementation issue in my code. Key Observations Success Rate: ~95% of users complete the flow successfully Failure Pattern: The remaining ~5% consistently fail at assertion generation Key Length: Logs show key length of 44 characters for both successful and failing cases Consistency: Users who experience the error tend to experience it consistently Platform: Issue observed across different iOS versions and device types Environment iOS App Attest implementation Using DCAppAttestService for both attestation and assertion Custom relying party server communication Issue affects ~5% of users consistently Key Implementation Details 1. Attestation Flow (Working) The attestation process works correctly: // Generate key and attest (successful for all users) self.attestService.generateKey { keyId, keyIdError in guard keyIdError == nil, let keyId = keyId else { return completionHandler(.failure(.dcError(keyIdError as! DCError))) } // Note: keyId length is consistently 44 characters for both successful and failing users // Attest key with Apple servers self.attestKey(keyId, clientData: clientData) { result in // ... verification with RP server // Key is successfully stored for ALL users (including those who later fail at assertion) } } 2. Assertion Flow (Failing for ~5% of Users with invalidInput) The assertion generation fails for a consistent subset of users: // Get assertion data from RP server self.assertRelyingParty.getAssertionData(kid, with: data) { result in switch result { case .success(let receivedData): let session = receivedData.session let clientData = receivedData.clientData let hash = clientData.toSHA256() // SHA256 hash of client data // THIS CALL FAILS WITH invalidInput for ~5% of users // Same keyId (44 chars) that worked for attestation self.attestService.generateAssertion(kid, clientDataHash: hash) { assertion, err in guard err == nil, let assertion = assertion else { // Error: DCError.invalidInput if let err = err as? DCError, err.code == .invalidKey { return reattestAndAssert(.invalidKey, completionHandler) } else { return completionHandler(.failure(.dcError(err as! DCError))) } } // ... verification logic } } } 3. Client Data Structure Client data JSON structure (identical for successful and failing users): // For attestation (works for all users) let clientData = ["challenge": receivedData.challenge] // For assertion (fails for ~5% of users with same structure) var clientData = ["challenge": receivedData.challenge] if let data = data { // Additional data for assertion clientData["account"] = data["account"] clientData["amount"] = data["amount"] } 4. SHA256 Hash Implementation extension Data { public func toSHA256() -> Data { return Data(SHA256.hash(data: self)) } } 5. Key Storage Implementation Using UserDefaults for key storage (works consistently for all users): private let keyStorageTag = "app-attest-keyid" func setKey(_ keyId: String) -> Result<(), KeyStorageError> { UserDefaults.standard.set(keyId, forKey: keyStorageTag) return .success(()) } func getKey() -> Result<String?, KeyStorageError> { let keyId = UserDefaults.standard.string(forKey: keyStorageTag) return .success(keyId) } Questions User-Specific Factors: Since this affects only ~5% of users consistently, could there be device-specific, iOS version-specific, or account-specific factors that cause invalidInput? Key State Validation: Is there any way to validate the state of an attested key before calling generateAssertion()? The key length (44 chars) appears normal for both successful and failing cases. Keychain vs UserDefaults: Could the issue be related to using UserDefaults instead of Keychain for key storage? Though this works for 95% of users. Race Conditions: Could there be subtle race conditions or timing issues that only affect certain users/devices? Error Recovery: Is there a recommended way to handle this error? Should we attempt re-attestation for these users? Additional Context & Debugging Attempts Consistent Failure: Users who experience this error typically experience it on every attempt Key Validation: Both successful and failing users have identical key formats (44 character strings) Device Diversity: Issue observed across different device models and iOS versions Server Logs: Our server successfully provides challenges and processes attestation for all users Re-attestation: Forcing re-attestation sometimes resolves the issue temporarily, but it often recurs The fact that 95% of users succeed with identical code suggests there might be some environmental or device-specific factor that we're not accounting for. Any insights into what could cause invalidInput for a subset of users would be invaluable.
2
0
161
Jun ’25
App Attest Suddenly Failing in Production — Error 4 (serverUnavailable)
Hi Apple Team and Community, We've encountered a sudden and widespread failure with the App Attest service starting today across multiple production apps and regions. The previously working implementation is now consistently returning the following error on iOS: The operation couldn’t be completed. (com.apple.devicecheck.error error 4.) (serverUnavailable) Despite the green status on Apple’s System Status page, this appears to be a backend issue—possibly infrastructure or DNS-related. Notably: The issue affects multiple apps. It is reproducible across different geographies. No code changes were made recently to the attestation logic. We previously reported a similar concern in this thread: App Attest Attestation Failing, but this new occurrence seems unrelated to any client-side cause. Update: An Apple engineer in this thread(https://developer.apple.com/forums/thread/782987) confirmed that the issue was due to a temporary DNS problem and has now been resolved. Can anyone else confirm seeing this today? Any insights from Apple would be appreciated to ensure continued stability. Thanks!
6
2
429
Jun ’25
How to use App Attest Environment?
Hi, I'm looking at adding App Attest to an app, and I think I understand the mechanics of the attestation process, but I'm having trouble figuring out how development and testing are supposed to work. Two main questions: The "App Attest Environment" -- the documentation says that attestation requests made in the .development sandbox environment don't affect the app's risk metrics, but I'm not sure how to actually use this sandbox. My understanding is that one of the things App Attest does is to ensure that your app has been appropriately signed by the App Store, so it knows that it hasn't been tampered with. But the docs say that App Store builds (and Test Flight and Developer Enterprise Program) always use the .production environment. Does App Attest actually work for local developer-build apps if you have this entitlement set? Presumably only on hardware devices since it requires the Secure Enclave? Does our headend have to do something different when verifying the public key and subsequent attested requests for an app that's using the .development sandbox? The docs do mention that a headend server should potentially track two keys per device/user pair so that it can have a production and development key. How does the headend know if a key is from the sandbox environment? Thanks!
0
0
115
Jun ’25
App Attest development server (data-development.appattest.apple.com) returns 403 for CBOR attestation request
Hi, I’m currently implementing App Attest attestation validation on the development server. However, I’m receiving a 403 Forbidden response when I POST a CBOR-encoded payload to the following endpoint: curl -X POST -H "Content-Type: application/cbor" --data-binary @payload.cbor 'https://data-development.appattest.apple.com' Here’s how I’m generating the CBOR payload in Java: Map&lt;String, Object&gt; payload = new HashMap&lt;&gt;(); payload.put("attestation", attestationBytes); // byte[] from DCAppAttestService payload.put("clientDataHash", clientDataHash); // SHA-256 hash of the challenge (byte[]) payload.put("keyId", keyIdBytes); // Base64-decoded keyId (byte[]) payload.put("appId", TEAM_ID + "." + BUNDLE_ID); // e.g., "ABCDE12345.com.example.app" ObjectMapper cborMapper = new ObjectMapper(new CBORFactory()); byte[] cborBody = cborMapper.writeValueAsBytes(payload); I’m unsure whether the endpoint is rejecting the payload format or if the endpoint itself is incorrect for this stage. I’d appreciate clarification on the following: 1. Is https://data-development.appattest.apple.com the correct endpoint for key attestation in a development environment? 2. Should this endpoint accept CBOR-encoded payloads, or is it only for JSON-based assertion validation? 3. Is there a current official Apple documentation that lists: • the correct URLs for key attestation and assertion validation (production and development), • or any server-side example code (e.g., Java, Python) for handling attestation/validation on the backend? So far, I couldn’t find an official document that explicitly describes the expected HTTP endpoints for these operations. If there’s a newer guide or updated API reference, I’d appreciate a link. Thanks in advance for your help.
0
0
121
May ’25
[App Attest] DNS resolution failure for attest.apple.com / development.apple.com
Hello, We are working on integrating app integrity verification into our service application, following Apple's App Attest and DeviceCheck guide. Our server issues a challenge to the client, which then sends the challenge, attestation, and keyId in CBOR format to Apple's App Attest server for verification. However, we are unable to reach both https://attest.apple.com and https://attest.development.apple.com due to network issues. These attempts have been made from both our internal corporate network and mobile hotspot environments. Despite adjusting DNS settings and other configurations, the issue persists. Are there alternative methods or solutions to address this problem? Any recommended network configurations or guidelines to successfully connect to Apple's App Attest servers would be greatly appreciated. Thank you.
2
0
102
May ’25
App Attest server unreachable – DNS or firewall issue suspected
Hello, We are working on integrating app integrity verification into our service application, following Apple's App Attest and DeviceCheck guide. Our server issues a challenge to the client, which then sends the challenge, attestation, and keyId in CBOR format to Apple's App Attest server for verification. However, we are unable to reach both https://attest.apple.com and https://attest.development.apple.com due to network issues. These attempts have been made from both our internal corporate network and mobile hotspot environments. Despite adjusting DNS settings and other configurations, the issue persists. Are there alternative methods or solutions to address this problem? Any recommended network configurations or guidelines to successfully connect to Apple's App Attest servers would be greatly appreciated. Thank you.
0
0
109
May ’25
Can you use App Attest in Enterprise Builds?
I'm a bit confused about if using App Attest is possible in enterprise builds. It shows up under identifiers in the apple dev portal and I can add it to my provisioning file and entitlements file. But if I go to keys I cannot create a key for it. This page implies it can be used for enterprise builds: After distributing your app through TestFlight, the App Store, or the Apple Developer Enterprise Program, your app ignores the entitlement you set and uses the production environment.
1
1
110
May ’25
Assistance in Implementing App Attestation
Hi, We're in the process of implementing Apple's App Integrity, but am getting stalled due to missing documents. Can anyone assist with this? We've been following https://developer.apple.com/documentation/devicecheck/validating-apps-that-connect-to-your-server to make the necessary updates, but have come up short with where the document references decoding the Attestation Object. Can we get more information here and how the decoding process work?
2
0
100
May ’25
Errors with Attestation on App
We recently deployed Attestation on our application, and for a majority of the 40,000 users it works well. We have about six customers who are failing attestation. In digging through debug logs, we're seeing this error "iOS assertion verification failed. Unauthorized access attempted." We're assuming that the UUID is blocked somehow on Apple side but we're stumped as to why. We had a customer come in and we could look at the phone, and best we can tell it's just a generic phone with no jailbroken or any malicious apps. How can we determine if the UUID is blocked?
3
0
152
May ’25
App Attest not working in production - started today
Hi, For some reason all implemented (and working before) App Attest code has stopped working. iOS is unable to get attestation returning "Operations could not be completed. (com.apple.devicecheck.error error 4.) (serverUnavailable)" On https://developer.apple.com/system-status/ I can see green dot but I suspect that infrastructure is not OK. This is happening with multiple of our apps in multiple geographical regions. Can anyone confirm these problems or know whether it is strictly connected to App Attest service availability?
21
19
2.2k
May ’25
App Attest receipts response 400
I tried to send it on the nodejs server I built. No success received 200 My work steps are as follows: The app executes “DCAppAttestService.shared.attestKey” to get receiptData from the acquired attestation. The app sends "receiptData.base64EncodedString()" to the server (code-1) Nodejs code (code-2) Because the app has been uploaded to TestFlight, I set the server IP to "data.appattest.apple.com" Is there something wrong with my steps? code-1 public func attestData(receipt:Data) { if DCDevice.current.isSupported { let sesh = URLSession(configuration: .default) var req = URLRequest(url: URL(string: "http://10.254.239.27:3000/attestationData")!) print(req) req.addValue("application/json", forHTTPHeaderField: "Content-Type") req.httpMethod = "POST" let data = try! JSONSerialization.data(withJSONObject: ["receipt": receipt.base64EncodedString()], options: []) req.httpBody = data let task = sesh.dataTask(with: req, completionHandler: { (data, response, error) in if let data = data, let jsonString = String(data: data, encoding: .utf8) { print(jsonString) } }) task.resume() } else { print("Platform is not supported. Make sure you aren't running in an emulator.") //self.stopActivity() } } code-2 versionRouter.post('/attestationData', function(req, response) { console.log("\n\n\n\n\n"); console.log("receiptApi"); var receiptBase64 = req.body.receipt; if (!receiptBase64) { return response.status(400).send({ error: 'Missing receipt data' }); } let binaryReceipt; if (typeof receiptBase64 === 'string') { const cleaned = receiptBase64.trim(); binaryReceipt = Buffer.from(cleaned, 'base64'); } if (Buffer.isBuffer(binaryReceipt)) { //binaryReceipt = receiptBase64; console.log("receipt is base64 或 Buffer: "+ Buffer.isBuffer(binaryReceipt)); } else { console.error('⚠️ receipt is not base64 or Buffer'); response.status(400).send("Receipt format error"); return; } var jwToken = jwt.sign({}, cert, { algorithm: 'ES256',header: { typ: undefined }, issuer: teamId, keyid: keyId}); var post_options = { host: 'data.appattest.apple.com', port: '443', path: '/v1/attestationData', method: 'POST', headers: { 'Authorization': jwToken, 'Content-Type': 'application/octet-stream', 'Content-Length': binaryReceipt.length } }; var post_req = https.request(post_options, function(res) { res.setEncoding('utf8'); console.log("📨 Apple Response Header:", res.headers); console.log("📨 Apple StatusCode:", res.statusCode); var data = ""; res.on('data', function (chunk) { data += chunk; }); res.on('end', function() { console.log(data); response.send({"status": res.statusCode, data: data}); }); }); post_req.on('error', function(e) { console.error('error:', e); response.status(500).send({ error: e.message }); }); post_req.write(binaryReceipt); post_req.end(); });
1
0
158
Apr ’25