Decrypt Apple Pay Payment Token with-in App - ios

How can I decrypt PKPaymentToken (Apple Pay Payment Token), in iOS (using Objective-C or Swift)?
It's recommended to decrypt the payment token at the server end (ideally done by the payment processor), but what if I want to decrypt the payment token data on the client side (iOS end).

Don't do this. It is a terrible idea. To decrypt the payment token requires your private key. You would have to embed this key into your app, which would allow anyone to take it and decrypt your payments. You should never decrypt the payment data on device for this reason.
Instead, store the private key securely on your servers and decrypt there, or see if your payment processor offers direct support for Apple Pay token decryption.

The process used to decrypt an Apple Pay payload is confidential and Apple only releases it to select payment gateway / processor partners. The private key you have for your merchant certificate to enable Apple Pay is used as part of this process but it is not the sole component and there is a complex series of steps to actually receive a card number (3-D Secure) usable for processing.
I would recommend signing up for a developer account at a place like Stripe and using their sandbox environment to test processing of encrypted Apple Pay payloads. Stripe's merchant tools will then expose redacted card info and other authorization details you may find helpful.

Related

Is there a way to upload screenshots with fastlane for 2FA enabled account without user interaction (e.g. via hardware key)?

Since Apple enforces AppleID accounts to be 2fa enabled and allows only application binary to be uploaded via API with app specific password I can not find a way to get the screenshots uploads fully automated.
I've tried obtaining session token as suggested in fastlane docs
fastlane spaceauth -u user#email.com
but obviously it also triggers 2FA procedure. Now the question is if this 2FA could be somehow fulfilled with hardware key like Yubico so that session token generation doesn't require any person involvement.
In addition to that it would be great if >100 AppleIDs could be secured with that single hardware key.
Any other solution is welcome. Thank you.
You should use an API key with the App Store Store Connect APIs. You can create API keys through AppStore Connect
The username/password authentication capability provided by FastLane was never officially supported by API. FastLane documentation recommends the use of API keys over username/password where possible:
It is recommended to use the API Key authentication when you are able to. The benefits include:
No 2FA needed
Better performance
Documented API
Increased reliability

How to verify realUserStatus value in Sign In With Apple

When signing in using Sign in with Apple for the first time, it returns a value realUserStatus as a part of ASAuthorizationAppleIDCredential in the iOS client. This value indicates whether Apple is confident that the user is real, or not (e.g. it's a script)
My question is how can I verify the value of realUserStatus in my backend authentication system?
Because the realUserStatus is returned to iOS client, and the client should tell my server whether it is a bot or not! How can I know if it's not just a script and telling the server that it is real?
Edit (additional clarification):
In Apple’s docs it says “ You can skip any additional fraud verification checks or CAPTCHAs that your app normally uses.” but when we use CAPTCHAs, the provider can verify the response, something either Apple doesn’t do, or I can’t find anywhere how to do it!
I just finished a call with an Apple engineer on WWDC online lab.
So from the iOS 14, the realUserIndicator is included in the identity token, and can be verified with the server.
For iOS 13 they don't have a solution.
This flag serves as a basic first validation, meant to be used by your frontend. The identification servers will return this value only when the user first uses Sign in with Apple in your app.
If you want to verify the user on the backend, you should use the user identity token (JWT). You get it from Apple's servers when the user signs in (read here: https://developer.apple.com/documentation/signinwithapplerestapi/authenticating_users_with_sign_in_with_apple).
If you want to verify the user on the upcoming sessions, as an existing user (without the user having to sign in every time), you should develop a system of your own, for creating, saving, and validating a token. Another option is to use Firebase auth framework, which supports apple sign-in.
if you send the fetched user’s information to app server(your backend) you can verify user by the identity token with a rest service.
Apple document says:
After your app receives the user information, you can verify their associated identity token with the server to confirm that the token is not expired and ensure it has not been tampered with or replayed to your app. For information about retrieving the identity token, see Authenticating Users with Sign in with Apple.
https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/verifying_a_user

iOS API Key: Is there an actual safe way to secure your API key when making http requests?

Currently, I am getting an API key from the server after logging in and using it to make http requests. I currently store the API key in the iPhone app's database. However, I've heard that I should store it in a keychain from a colleague. So, I searched on Stackoverflow and seen questions regarding this. It seems this isn't really a secure way of storing API keys at all.
Secure keys in iOS App scenario, is it safe?
In iOS, how can I store a secret "key" that will allow me to communicate with my server?
I don't know a way to stop hackers from reverse engineering to get the API key from the iOS app. A user on StackOverflow basically said it will only overcomplicate things for little to no benefits.
I need to find the post, but someone recommended to just make sure you're making a secure API request (SSL certificate) and you have a way to remove the API key if someone is hacked.
As already pointed out by #jake you should use a token tied up only to the user instead of an Api Key for all users, but other enhancements can be done for further protect your App when doing the http requests.
The user token can be a signed JWT token and then you can enhance the security of the communication between your server and the App with Certificate Pinning in order to protect against Man in the Middle Attacks.
Other techniques like the use of OAUTH2 and hiding secrets can be used to enhance the security of your App and you can read more about it here.
Keep in mind that Certificate Pinning can be bypassed by hooking frameworks such as Xposed that contain modules specific to bypass the pinning, but still another layer of security that you should not discard once it will increase the effort necessary to hack your App on the device and will protect your App against Man in the Middle Attacks.
For ultimately security between your App and the back-end you should use an App integrity attestation service, that will guarantee at run-time that your App was not tampered or is not running in a rooted device by using an SDK integrated in you App and a service running in the cloud.
On successful attestation of the App integrity a JWT token is issued and signed with a secret that only the back-end of your App and the attestation service in the cloud are aware and on failure the JWT is signed with a fake secret that the App back-end does not know, allowing this way for the App back-end to only serve requests when it can verify the signature in the JWT token and refuse them when it fails the verification.
Once the secret used by the cloud attestation service is not known by the App it is not possible to reverse engineer it at run-time even when the App is tampered, running in a rooted device or communicating over a connection that is being the target of a Man in the Middle Attack.
You can find such a service in Approov that have SDKs for several platforms, including IOS. The integration will also need a small check in the App back-end code to verify the JWT token in order the back-end can protect itself against fraudulent use.
JWT Token
Token Based Authentication
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.
Certificate Pinning
Pinning is the process of associating a host with their expected X509 certificate or public key. Once a certificate or public key is known or seen for a host, the certificate or public key is associated or 'pinned' to the host. If more than one certificate or public key is acceptable, then the program holds a pinset (taking from Jon Larimer and Kenny Root Google I/O talk). In this case, the advertised identity must match one of the elements in the pinset.
OAUTH2
The OAuth 2.0 authorization framework enables a third-party
application to obtain limited access to an HTTP service, either on
behalf of a resource owner by orchestrating an approval interaction
between the resource owner and the HTTP service, or by allowing the
third-party application to obtain access on its own behalf. This
specification replaces and obsoletes the OAuth 1.0 protocol described
in RFC 5849.
Disclaimer: I work at Approov.
A more secure mechanism would be to return an authentication token on login. This authentication token should be unique to the user. If you have proper authorization and security mechanisms on the backend (to mitigate DDOS attacks, injection attacks, users accessing other user’s data, etc) then who cares if they get their authorization token from the keychain or wherever it is stored? Since the authentication token is tied to their account you could just invalidate the token so it stops working if the user is malicious. And you could even disable their account altogether if you have the right mechanisms in place on the backend.
Many of the security mechanisms can be automated on the backend. Platforms like AWS can easily be configured to automatically disable accounts that are doing certain malicious calls to your backend.

Include digital certificate in AppStore-distributed iOS app

I have an endpoint in which the server has to be sure of the authenticity of the client making the API calls. I therefore imagined the best way to do it is to include something like a digital certificate or a secret in the client which would have to be encrypted and distributed within the binary that goes to the AppStore. How could I add such a certificate in order for it to be safe? What alternatives would I have if not possible?
Apple helpfully provides a set of APIs that would allow you to store a certificate securely, and that would probably be what you should use. Past that, there is no way to guarantee that your certificate is not stolen by a sophisticated attacker; any key you distribute can be stolen, unless you are transmitting it over a secure channel to a trusted recipient.

OAuth to secure iOS MDM enrolment process

I have some MDM solution that we've developed through which we want to support managing iOS devices. Even though we'd already been able to successfully enrol and manage iOS devices via the same, I am trying to figure out a way to secure all web service invocations with OAuth, which take place between the native app running on iOS devices, connecting to the Enrolment and other APIs deployed as part of the MDM solution. Apparently, we've got limited control over modifying the native app to embed OAuth access tokens in the form of HTTP headers or some other means to be able to send those access tokens across to the MDM APIs, as the app logic cannot be modified. Do we have any configuration in the Enterprise App that runs on iOS devices to enable OAuth (or any other form of authentication) or some other means, which I can effectively use to get my requirement implemented?
iOS enrollment flow associate with a challenge token in the SCEP payload (mentioned as Challenge). Once you do the authentication from MDM server side there needs to be a unique token generated based on your user identity and embed that in this SCEP payload. For subsequent enrollment calls this token is passed and once the enrollment success this can be fetched and validate the user. Ideally this is just a way to link the device to a specific user which could be a temporary token generated at your MDM server end which link to a user identity or something related. To follow that you could apply OAuth password grant type and get the token once the authentication happens. Then this OAuth token can be then set as this challenge token for future use. But unlike in other OAuth communications iOS will not send this token in header as the bearer rather this will be embedded in the xml payload with proper encryption and signing in place.
Further iOS support protocol extension to validate users with open directory service using an auth token. This will by default have the ability to communicate back and forth using the checkin endpoint.

Resources